الکوئنت: شروع کردن
- معرفی
- تعریف مدل ها
- بازیابی مدل ها
- بازیابی مدل های منفرد / مصالح
- درج و به روز رسانی مدل ها
- حذف مدل ها
- شبیه سازی مدل ها
- محدوده های پرس و جو
- مقایسه مدل ها
- مناسبت ها
معرفی
ORM Eloquent همراه با لاراول یک پیاده سازی ActiveRecord زیبا و ساده برای کار با پایگاه داده شما ارائه می دهد. هر جدول پایگاه داده یک "مدل" مربوطه دارد که برای تعامل با آن جدول استفاده می شود. مدلها به شما امکان میدهند دادههای جداول خود را پرس و جو کنید، و همچنین رکوردهای جدیدی را در جدول وارد کنید.
قبل از شروع، حتماً اتصال پایگاه داده را در پیکربندی کنید
config/database.php
.
برای اطلاعات بیشتر در مورد پیکربندی پایگاه داده خود، مستندات را
بررسی کنید
.
تعریف مدل ها
برای شروع، بیایید یک مدل Eloquent ایجاد کنیم.
مدلها معمولاً در
app
دایرکتوری زندگی میکنند، اما شما میتوانید آنها را در هر جایی که
میتواند بهطور خودکار مطابق با
composer.json
فایل شما بارگذاری شود، قرار دهید.
همه مدل های Eloquent
Illuminate\Database\Eloquent\Model
کلاس را گسترش می دهند.
ساده ترین راه برای ایجاد یک نمونه مدل استفاده از
make:model
دستور Artisan
است :
php artisan make:model Flight
اگر می خواهید
هنگام ایجاد مدل، یک
انتقال پایگاه داده
--migration
ایجاد کنید، می توانید از گزینه یا استفاده کنید
-m
:
php artisan make:model Flight --migration php artisan make:model Flight -m
قراردادهای مدل الکوئنت
حال، بیایید به یک مدل مثال نگاه کنیم ، که از آن برای بازیابی و ذخیره
اطلاعات از
جدول پایگاه داده
Flight
خود استفاده خواهیم کرد :
flights
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ //}
نام جدول
توجه داشته باشید که ما به Eloquent نگفتیم که از کدام جدول برای
Flight
مدل خود استفاده کنیم.
طبق قرارداد، نام جمع «snake case» به عنوان نام جدول استفاده می شود، مگر
اینکه نام دیگری به صراحت مشخص شده باشد.
بنابراین، در این مورد، Eloquent فرض می کند که
Flight
مدل رکوردها را در
flights
جدول ذخیره می کند.
table
شما می توانید با تعریف یک ویژگی در مدل خود
یک جدول سفارشی را مشخص کنید :
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The table associated with the model. * * @var string */ protected $table = 'my_flights';}
کلیدهای اصلی
Eloquent همچنین فرض می کند که هر جدول دارای یک ستون کلید اصلی به نام است
id
.
شما می توانید یک
$primaryKey
ویژگی محافظت شده را برای لغو این قرارداد تعریف کنید:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The primary key associated with the table. * * @var string */ protected $primaryKey = 'flight_id';}
علاوه بر این، Eloquent فرض میکند که کلید اصلی یک مقدار صحیح افزایشی است،
به این معنی که به طور پیشفرض کلید اصلی به طور خودکار به یک فرستاده میشود
int
.
اگر می خواهید از یک کلید اصلی غیر افزایشی یا غیر عددی استفاده کنید، باید
$incrementing
ویژگی عمومی در مدل خود را به صورت زیر تنظیم کنید
false
:
<?php class Flight extends Model{ /** * Indicates if the IDs are auto-incrementing. * * @var bool */ public $incrementing = false;}
اگر کلید اصلی شما یک عدد صحیح نیست، باید
$keyType
ویژگی محافظت شده در مدل خود را به صورت زیر تنظیم کنید
string
:
<?php class Flight extends Model{ /** * The "type" of the auto-incrementing ID. * * @var string */ protected $keyType = 'string';}
مهر زمانی
بهطور پیشفرض، Eloquent انتظار دارد
created_at
و
updated_at
ستونهایی در جداول شما وجود داشته باشد.
اگر نمیخواهید این ستونها بهطور خودکار توسط Eloquent مدیریت شوند، ویژگی
$timestamps
مدل خود را روی
false
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * Indicates if the model should be timestamped. * * @var bool */ public $timestamps = false;}
اگر میخواهید قالب مُهرهای زمانی خود را سفارشی کنید،
$dateFormat
ویژگی را روی مدل خود تنظیم کنید.
این ویژگی نحوه ذخیره ویژگی های تاریخ در پایگاه داده و همچنین فرمت آنها را
در زمانی که مدل به صورت سریال در یک آرایه یا JSON ذخیره می شود، تعیین می کند:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The storage format of the model's date columns. * * @var string */ protected $dateFormat = 'U';}
اگر میخواهید نام ستونهای مورد استفاده برای ذخیره مُهرهای زمانی را
سفارشی کنید، میتوانید ثابتها
CREATED_AT
و را
UPDATED_AT
در مدل خود تنظیم کنید:
<?php class Flight extends Model{ const CREATED_AT = 'creation_date'; const UPDATED_AT = 'last_update';}
اتصال به پایگاه داده
به طور پیشفرض، همه مدلهای Eloquent از اتصال پایگاه داده پیشفرض
پیکربندی شده برای برنامه شما استفاده میکنند.
اگر می خواهید اتصال دیگری برای مدل مشخص کنید، از
$connection
ویژگی استفاده کنید:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The connection name for the model. * * @var string */ protected $connection = 'connection-name';}
مقادیر مشخصه پیش فرض
اگر میخواهید مقادیر پیشفرض را برای برخی از ویژگیهای مدل خود تعریف
کنید، میتوانید یک
$attributes
ویژگی در مدل خود تعریف کنید:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The model's default values for attributes. * * @var array */ protected $attributes = [ 'delayed' => false, ];}
بازیابی مدل ها
هنگامی که یک مدل و جدول پایگاه داده مرتبط با آن را ایجاد کردید ، آماده شروع بازیابی داده ها از پایگاه داده خود هستید. هر مدل Eloquent را به عنوان یک سازنده پرس و جو قدرتمند در نظر بگیرید که به شما امکان می دهد به راحتی جدول پایگاه داده مرتبط با مدل را جستجو کنید. مثلا:
<?php $flights = App\Flight::all(); foreach ($flights as $flight) { echo $flight->name;}
اضافه کردن محدودیت های اضافی
روش Eloquent
all
تمام نتایج را در جدول مدل برمی گرداند.
از آنجایی که هر مدل Eloquent به عنوان
سازنده پرس و جو
عمل می کند ، می توانید محدودیت هایی را نیز به کوئری ها اضافه کنید و سپس
از
get
روش برای بازیابی نتایج استفاده کنید:
$flights = App\Flight::where('active', 1) ->orderBy('name', 'desc') ->take(10) ->get();
از آنجایی که مدل های Eloquent سازنده پرس و جو هستند، باید همه روش های موجود در سازنده query را مرور کنید . می توانید از هر یک از این روش ها در پرس و جوهای Eloquent خود استفاده کنید.
مدل های با طراوت
میتوانید با استفاده از روشهای
fresh
و مدلها را بهروزرسانی کنید
refresh
.
این
fresh
روش مدل را از پایگاه داده بازیابی می کند.
نمونه مدل موجود تحت تأثیر قرار نخواهد گرفت:
$flight = App\Flight::where('number', 'FR 900')->first(); $freshFlight = $flight->fresh();
این
refresh
روش مدل موجود را با استفاده از داده های تازه از پایگاه داده هیدراته می
کند.
علاوه بر این، تمام روابط بارگذاری شده آن نیز به روز می شوند:
$flight = App\Flight::where('number', 'FR 900')->first(); $flight->number = 'FR 456'; $flight->refresh(); $flight->number; // "FR 900"
مجموعه ها
برای روش های Eloquent مانند
all
و
get
که چندین نتیجه را بازیابی می کنند، یک نمونه از
Illuminate\Database\Eloquent\Collection
برگردانده می شود.
این
Collection
کلاس
انواع روش های مفیدی را
برای کار با نتایج Eloquent ارائه می دهد:
$flights = $flights->reject(function ($flight) { return $flight->cancelled;});
همچنین می توانید مانند یک آرایه روی مجموعه حلقه بزنید:
foreach ($flights as $flight) { echo $flight->name;}
نتایج تکه تکه شدن
اگر نیاز به پردازش هزاران رکورد Eloquent دارید، از
chunk
دستور استفاده کنید.
این
chunk
روش «تکهای» از مدلهای Eloquent را بازیابی میکند و آنها را
Closure
برای پردازش به یک داده میدهد.
استفاده از این
chunk
روش باعث حفظ حافظه در هنگام کار با مجموعه نتایج بزرگ می شود:
Flight::chunk(200, function ($flights) { foreach ($flights as $flight) { // }});
اولین آرگومان ارسال شده به متد، تعداد رکوردهایی است که می خواهید در هر "تکه" دریافت کنید. بسته شدن به عنوان آرگومان دوم برای هر تکه ای که از پایگاه داده بازیابی می شود فراخوانی می شود. یک پرس و جو از پایگاه داده برای بازیابی هر تکه از رکوردهای ارسال شده به Close اجرا می شود.
استفاده از مکان نما
این
cursor
روش به شما اجازه می دهد تا با استفاده از مکان نما، رکوردهای پایگاه داده
خود را تکرار کنید، که فقط یک پرس و جو را اجرا می کند.
هنگام پردازش مقادیر زیادی داده،
cursor
ممکن است از این روش برای کاهش بسیار زیاد استفاده از حافظه استفاده شود:
foreach (Flight::where('foo', 'bar')->cursor() as $flight) { //}
cursor
یک نمونه را
برمی گرداند
Illuminate\Support\LazyCollection
.
مجموعههای تنبل
به شما این امکان را میدهند که از بسیاری از روشهای جمعآوری موجود در
مجموعههای معمولی لاراول استفاده کنید در حالی که هر بار فقط یک مدل را در حافظه بارگذاری میکنید:
$users = App\User::cursor()->filter(function ($user) { return $user->id > 500;}); foreach ($users as $user) { echo $user->id;}
سوالات فرعی پیشرفته
استعلام فرعی انتخاب می کند
Eloquent همچنین پشتیبانی پیشرفته subquery را ارائه می دهد که به شما امکان
می دهد اطلاعات را از جداول مرتبط در یک پرس و جو استخراج کنید.
به عنوان مثال، بیایید تصور کنیم که یک جدول پرواز
destinations
و یک جدول از
flights
مقصد داریم.
جدول
flights
شامل
arrived_at
ستونی است که نشان می دهد پرواز چه زمانی به مقصد رسیده است.
با استفاده از قابلیت subquery موجود در روشها
select
و
addSelect
، میتوانیم همه پروازها
destinations
و نام پروازی را که اخیراً به آن مقصد رسیده است، با استفاده از یک جستجو
انتخاب کنیم:
use App\Destination;use App\Flight; return Destination::addSelect(['last_flight' => Flight::select('name') ->whereColumn('destination_id', 'destinations.id') ->orderBy('arrived_at', 'desc') ->limit(1)])->get();
سفارش فرعی
علاوه بر این، تابع سازنده پرس
orderBy
و جو از سوالات فرعی پشتیبانی می کند.
ممکن است از این قابلیت برای مرتبسازی همه مقصدها بر اساس زمان رسیدن آخرین
پرواز به آن مقصد استفاده کنیم.
باز هم، این ممکن است در حین اجرای یک کوئری در مقابل پایگاه داده انجام
شود:
return Destination::orderByDesc( Flight::select('arrived_at') ->whereColumn('destination_id', 'destinations.id') ->orderBy('arrived_at', 'desc') ->limit(1))->get();
بازیابی مدل های منفرد / مصالح
علاوه بر بازیابی همه رکوردهای یک جدول داده شده، میتوانید تک رکوردها را
با استفاده از
find
،
first
و یا بازیابی کنید
firstWhere
.
این متدها به جای برگرداندن مجموعه ای از مدل ها، یک نمونه مدل را برمی
گرداند:
// Retrieve a model by its primary key...$flight = App\Flight::find(1); // Retrieve the first model matching the query constraints...$flight = App\Flight::where('active', 1)->first(); // Shorthand for retrieving the first model matching the query constraints...$flight = App\Flight::firstWhere('active', 1);
همچنین میتوانید
find
متد را با آرایهای از کلیدهای اصلی فراخوانی کنید که مجموعهای از رکوردهای
منطبق را برمیگرداند:
$flights = App\Flight::find([1, 2, 3]);
گاهی اوقات ممکن است بخواهید اولین نتیجه یک پرس و جو را بازیابی کنید یا
اگر نتیجه ای یافت نشد، اقدامات دیگری را انجام دهید.
این
firstOr
متد اولین نتیجه ای را که پیدا شد برمی گرداند یا اگر نتیجه ای پیدا نشد،
فراخوانی داده شده را اجرا می کند.
نتیجه فراخوانی نتیجه روش در نظر گرفته می شود
firstOr
:
$model = App\Flight::where('legs', '>', 100)->firstOr(function () { // ...});
این
firstOr
روش همچنین آرایه ای از ستون ها را برای بازیابی می پذیرد:
$model = App\Flight::where('legs', '>', 100) ->firstOr(['id', 'legs'], function () { // ... });
موارد استثنا یافت نشد
گاهی اوقات ممکن است بخواهید در صورت پیدا نشدن یک مدل استثنایی ایجاد کنید.
این به ویژه در مسیرها یا کنترلرها مفید است.
متدهای
findOrFail
و
firstOrFail
اولین نتیجه پرس و جو را بازیابی خواهند کرد.
با این حال، اگر نتیجه ای یافت نشد، یک
Illuminate\Database\Eloquent\ModelNotFoundException
پرتاب می شود:
$model = App\Flight::findOrFail(1); $model = App\Flight::where('legs', '>', 100)->firstOrFail();
در صورت عدم وجود استثنا، یک
404
پاسخ HTTP به طور خودکار برای کاربر ارسال می شود.
404
هنگام استفاده از این روشها،
نوشتن چکهای صریح برای بازگشت پاسخها ضروری نیست :
Route::get('/api/flights/{id}', function ($id) { return App\Flight::findOrFail($id);});
بازیابی مصالح
همچنین می توانید از
count
,
sum
,
max
, و سایر
روش های انبوه
ارائه شده توسط
سازنده پرس و جو
استفاده کنید .
این روش ها به جای نمونه کامل مدل، مقدار اسکالر مناسب را برمی گرداند:
$count = App\Flight::where('active', 1)->count(); $max = App\Flight::where('active', 1)->max('price');
درج و به روز رسانی مدل ها
درج می کند
برای ایجاد یک رکورد جدید در پایگاه داده، یک نمونه مدل جدید ایجاد کنید،
ویژگی ها را روی مدل تنظیم کنید، سپس متد را فراخوانی کنید
save
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use App\Flight;use Illuminate\Http\Request; class FlightController extends Controller{ /** * Create a new flight instance. * * @param Request $request * @return Response */ public function store(Request $request) { // Validate the request... $flight = new Flight; $flight->name = $request->name; $flight->save(); }}
name
در این مثال، پارامتر درخواست HTTP ورودی را به
name
ویژگی نمونه مدل
اختصاص می دهیم
App\Flight
.
وقتی متد را فراخوانی می کنیم
save
، یک رکورد در پایگاه داده درج می شود.
هنگامی که متد فراخوانی می شود، مهرهای زمانی
created_at
و
updated_at
به طور خودکار تنظیم می شوند
save
، بنابراین نیازی به تنظیم دستی آنها نیست.
به روز رسانی ها
این
save
روش همچنین ممکن است برای بهروزرسانی مدلهایی که از قبل در پایگاه داده
وجود دارد استفاده شود.
برای بهروزرسانی یک مدل، باید آن را بازیابی کنید، هر ویژگی را که
میخواهید بهروزرسانی کنید تنظیم کنید و سپس
save
متد را فراخوانی کنید.
باز هم،
updated_at
مهر زمانی به طور خودکار به روز می شود، بنابراین نیازی به تنظیم دستی مقدار
آن نیست:
$flight = App\Flight::find(1); $flight->name = 'New Flight Name'; $flight->save();
به روز رسانی های انبوه
همچنین میتوان بهروزرسانیها را در برابر هر تعداد مدلی که با یک پرسوجو
مطابقت دارند انجام داد.
در این مثال، تمام پروازهایی که دارای
active
یک از هستند و دارای
destination
یک هستند
San Diego
، بهعنوان تاخیردار علامتگذاری میشوند:
App\Flight::where('active', 1) ->where('destination', 'San Diego') ->update(['delayed' => 1]);
این
update
روش انتظار دارد آرایهای از جفتهای ستون و مقادیر نشان دهنده ستونهایی
باشد که باید بهروزرسانی شوند.
هنگام صدور یک بهروزرسانی انبوه از طریق Eloquent، رویدادهای
saving
,saved
,updating
وupdated
مدل برای مدلهای بهروزرسانی شده فعال نمیشوند. این به این دلیل است که مدل ها در هنگام صدور یک به روز رسانی انبوه هرگز بازیابی نمی شوند.
بررسی تغییرات صفت
Eloquent روشهای
isDirty
،
isClean
و و
wasChanged
را برای بررسی وضعیت داخلی مدل شما و تعیین اینکه چگونه ویژگیهای آن نسبت
به زمانی که بارگذاری اولیه شده بودند، تغییر کرده است، ارائه میکند.
این
isDirty
روش تعیین میکند که آیا از زمان بارگذاری مدل، ویژگیهایی تغییر کرده است
یا خیر.
شما می توانید یک نام مشخصه را برای تعیین اینکه آیا یک ویژگی خاص کثیف است
ارسال کنید.
متد
isClean
مخالف است
isDirty
و یک آرگومان ویژگی اختیاری را نیز می پذیرد:
$user = User::create([ 'first_name' => 'Taylor', 'last_name' => 'Otwell', 'title' => 'Developer',]); $user->title = 'Painter'; $user->isDirty(); // true$user->isDirty('title'); // true$user->isDirty('first_name'); // false $user->isClean(); // false$user->isClean('title'); // false$user->isClean('first_name'); // true $user->save(); $user->isDirty(); // false$user->isClean(); // true
این
wasChanged
روش تعیین میکند که آیا در آخرین ذخیرهسازی مدل در چرخه درخواست فعلی، هیچ
ویژگی تغییر کرده است یا خیر.
همچنین می توانید یک نام مشخصه را ارسال کنید تا ببینید آیا یک ویژگی خاص
تغییر کرده است یا خیر:
$user = User::create([ 'first_name' => 'Taylor', 'last_name' => 'Otwell', 'title' => 'Developer',]); $user->title = 'Painter';$user->save(); $user->wasChanged(); // true$user->wasChanged('title'); // true$user->wasChanged('first_name'); // false
این
getOriginal
روش یک آرایه حاوی ویژگی های اصلی مدل را بدون توجه به هرگونه تغییری از
زمان بارگذاری مدل برمی گرداند.
برای بدست آوردن مقدار اصلی یک ویژگی خاص، می توانید یک نام مشخصه را ارسال
کنید:
$user = User::find(1); $user->name; // John$user->email; // john@example.com $user->name = "Jack";$user->name; // Jack $user->getOriginal('name'); // John$user->getOriginal(); // Array of original attributes...
تکلیف انبوه
همچنین می توانید از این
create
روش برای ذخیره یک مدل جدید در یک خط استفاده کنید.
نمونه مدل درج شده از متد به شما بازگردانده می شود.
با این حال، قبل از انجام این کار، باید یک
fillable
یا
guarded
ویژگی را در مدل مشخص کنید، زیرا تمام مدلهای Eloquent به طور پیشفرض از
انتساب انبوه محافظت میکنند.
آسیبپذیری انبوه انتساب زمانی رخ میدهد که کاربر یک پارامتر HTTP
غیرمنتظره را از طریق یک درخواست ارسال میکند و آن پارامتر ستونی را در پایگاه داده شما تغییر میدهد که
انتظارش را نداشتید.
به عنوان مثال، یک کاربر مخرب ممکن است
is_admin
پارامتری را از طریق یک درخواست HTTP ارسال کند، که سپس به روش مدل شما
منتقل میشود
create
و به کاربر اجازه میدهد تا خود را به یک مدیر افزایش دهد.
بنابراین، برای شروع، باید مشخص کنید که کدام ویژگی مدل را میخواهید قابل
تخصیص جرم کنید.
می توانید این کار را با استفاده از
$fillable
ویژگی روی مدل انجام دهید.
به عنوان مثال، بیایید
name
ویژگی جرم مدل خود را
Flight
قابل تخصیص کنیم:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Flight extends Model{ /** * The attributes that are mass assignable. * * @var array */ protected $fillable = ['name'];}
هنگامی که ویژگی ها را قابل انتساب جرم قرار دادیم، می توانیم از
create
روش برای درج یک رکورد جدید در پایگاه داده استفاده کنیم.
متد
create
نمونه مدل ذخیره شده را برمی گرداند:
$flight = App\Flight::create(['name' => 'Flight 10']);
اگر قبلاً یک نمونه مدل دارید، می توانید از
fill
روش برای پر کردن آن با آرایه ای از ویژگی ها استفاده کنید:
$flight->fill(['name' => 'Flight 22']);
اجازه واگذاری انبوه
اگر می خواهید همه ویژگی ها را قابل انتساب جرم قرار دهید، می توانید
$guarded
ویژگی را به عنوان یک آرایه خالی تعریف کنید:
/** * The attributes that aren't mass assignable. * * @var array */protected $guarded = [];
سایر روش های ایجاد
firstOrCreate
/
firstOrNew
دو روش دیگر وجود دارد که میتوانید برای ایجاد مدلها با تخصیص انبوه
ویژگیها استفاده کنید:
firstOrCreate
و
firstOrNew
.
این
firstOrCreate
روش سعی خواهد کرد یک رکورد پایگاه داده را با استفاده از جفت های ستون /
مقدار داده شده پیدا کند.
اگر مدل را نتوان در پایگاه داده پیدا کرد، یک رکورد با ویژگی های پارامتر
اول، همراه با ویژگی های پارامتر دوم اختیاری درج می شود.
این
firstOrNew
روش، مانند
firstOrCreate
تلاش برای یافتن رکوردی در پایگاه داده مطابق با ویژگی های داده شده است.
با این حال، اگر یک مدل پیدا نشد، یک نمونه مدل جدید برگردانده خواهد شد.
توجه داشته باشید که مدل بازگشتی توسط
firstOrNew
هنوز در پایگاه داده حفظ نشده است.
save
برای تداوم آن
باید به صورت دستی تماس بگیرید :
// Retrieve flight by name, or create it if it doesn't exist...$flight = App\Flight::firstOrCreate(['name' => 'Flight 10']); // Retrieve flight by name, or create it with the name, delayed, and arrival_time attributes...$flight = App\Flight::firstOrCreate( ['name' => 'Flight 10'], ['delayed' => 1, 'arrival_time' => '11:30']); // Retrieve by name, or instantiate...$flight = App\Flight::firstOrNew(['name' => 'Flight 10']); // Retrieve by name, or instantiate with the name, delayed, and arrival_time attributes...$flight = App\Flight::firstOrNew( ['name' => 'Flight 10'], ['delayed' => 1, 'arrival_time' => '11:30']);
updateOrCreate
همچنین ممکن است با موقعیت هایی روبرو شوید که بخواهید یک مدل موجود را به
روز کنید یا اگر مدلی وجود ندارد، یک مدل جدید ایجاد کنید.
لاراول
updateOrCreate
روشی برای انجام این کار در یک مرحله ارائه می دهد.
مانند
firstOrCreate
متد،
updateOrCreate
مدل را ادامه میدهد، بنابراین نیازی به فراخوانی نیست
save()
:
// If there's a flight from Oakland to San Diego, set the price to $99.// If no matching model exists, create one.$flight = App\Flight::updateOrCreate( ['departure' => 'Oakland', 'destination' => 'San Diego'], ['price' => 99, 'discounted' => 1]);
حذف مدل ها
برای حذف یک مدل،
delete
متد را در یک نمونه مدل فراخوانی کنید:
$flight = App\Flight::find(1); $flight->delete();
حذف یک مدل موجود توسط کلید
در مثال بالا، قبل از فراخوانی
delete
متد، مدل را از پایگاه داده بازیابی می کنیم.
با این حال، اگر کلید اصلی مدل را میدانید، میتوانید با فراخوانی متد، مدل
را بدون بازیابی صریح حذف کنید
destroy
.
این روش علاوه بر یک کلید اصلی به عنوان آرگومان خود،
destroy
چندین کلید اصلی، آرایه ای از کلیدهای اصلی یا
مجموعه ای
از کلیدهای اصلی را می پذیرد:
App\Flight::destroy(1); App\Flight::destroy(1, 2, 3); App\Flight::destroy([1, 2, 3]); App\Flight::destroy(collect([1, 2, 3]));
این
destroy
متد هر مدل را به صورت جداگانه بارگذاری می کند وdelete
متد را بر روی آنها فراخوانی می کند تاdeleting
وقایعdeleted
فعال شوند.
حذف مدل ها با پرس و جو
همچنین می توانید یک دستور حذف را روی مجموعه ای از مدل ها اجرا کنید. در این مثال، ما تمام پروازهایی را که به عنوان غیرفعال علامت گذاری شده اند حذف می کنیم. مانند بهروزرسانیهای انبوه، حذفهای انبوه هیچ رویداد مدلی را برای مدلهایی که حذف میشوند فعال نمیکند:
$deletedRows = App\Flight::where('active', 0)->delete();
هنگام اجرای دستور حذف انبوه از طریق Eloquent، رویدادهای مدل
deleting
وdeleted
برای مدلهای حذف شده فعال نمیشوند. این به این دلیل است که مدل ها در هنگام اجرای دستور حذف هرگز بازیابی نمی شوند.
حذف نرم
Eloquent علاوه بر حذف واقعی رکوردها از پایگاه داده شما، می تواند مدل های
"نرم افزار" را نیز حذف کند.
وقتی مدل ها به نرمی حذف می شوند، در واقع از پایگاه داده شما حذف نمی شوند.
در عوض، یک
deleted_at
ویژگی روی مدل تنظیم شده و در پایگاه داده درج می شود.
اگر مدلی دارای مقدار غیر تهی باشد
deleted_at
، مدل به نرمی حذف شده است.
برای فعال کردن حذف های نرم برای یک مدل، از
Illuminate\Database\Eloquent\SoftDeletes
ویژگی روی مدل استفاده کنید:
<?php namespace App; use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\SoftDeletes; class Flight extends Model{ use SoftDeletes;}
این ویژگی به طور خودکار ویژگی را به یک نمونه / برای شما
SoftDeletes
ارسال می کند .deleted_at
DateTime
Carbon
همچنین باید
deleted_at
ستون را به جدول پایگاه داده خود اضافه کنید.
سازنده طرحواره
لاراول
حاوی یک روش کمکی برای ایجاد این ستون است:
public function up(){ Schema::table('flights', function (Blueprint $table) { $table->softDeletes(); });} public function down(){ Schema::table('flights', function (Blueprint $table) { $table->dropSoftDeletes(); });}
حالا وقتی
delete
متد را روی مدل فراخوانی می کنید،
deleted_at
ستون روی تاریخ و زمان فعلی تنظیم می شود.
و هنگام جستجوی مدلی که از حذف های نرم استفاده می کند، مدل های حذف شده نرم
به طور خودکار از همه نتایج پرس و جو حذف می شوند.
برای تعیین اینکه آیا یک نمونه مدل داده شده به نرمی حذف شده است، از
trashed
روش استفاده کنید:
if ($flight->trashed()) { //}
پرس و جو از مدل های حذف شده نرم
از جمله مدل های نرم حذف شده
همانطور که در بالا ذکر شد، مدل های حذف شده به صورت خودکار از نتایج پرس و
جو حذف می شوند.
با این حال، میتوانید مدلهای پاکشده نرم را مجبور کنید با استفاده از
withTrashed
روش موجود در پرسوجو، در یک مجموعه نتیجه ظاهر شوند:
$flights = App\Flight::withTrashed() ->where('account_id', 1) ->get();
این
withTrashed
روش همچنین ممکن است در یک پرس و جو
رابطه
استفاده شود :
$flight->history()->withTrashed()->get();
بازیابی فقط مدل های نرم حذف شده
این
onlyTrashed
روش
فقط
مدل های حذف شده نرم را بازیابی می کند:
$flights = App\Flight::onlyTrashed() ->where('airline_id', 1) ->get();
بازیابی مدل های نرم حذف شده
گاهی اوقات ممکن است بخواهید یک مدل نرم افزاری حذف شده را حذف کنید.
برای بازگرداندن یک مدل نرم افزاری حذف شده به حالت فعال، از
restore
روش روی نمونه مدل استفاده کنید:
$flight->restore();
همچنین میتوانید از این
restore
روش در یک کوئری برای بازیابی سریع چندین مدل استفاده کنید.
مجدداً، مانند سایر عملیاتهای «انبوه»، این کار هیچ رویداد مدلی را برای
مدلهایی که بازیابی میشوند، اجرا نمیکند:
App\Flight::withTrashed() ->where('airline_id', 1) ->restore();
مانند
withTrashed
روش، روش ممکن است در
روابط
restore
نیز استفاده شود
:
$flight->history()->restore();
حذف دائمی مدل ها
گاهی اوقات ممکن است لازم باشد یک مدل را واقعاً از پایگاه داده خود حذف
کنید.
برای حذف دائمی یک مدل نرم افزاری حذف شده از پایگاه داده، از
forceDelete
روش زیر استفاده کنید:
// Force deleting a single model instance...$flight->forceDelete(); // Force deleting all related models...$flight->history()->forceDelete();
شبیه سازی مدل ها
می توانید با استفاده از
replicate
روش، یک کپی ذخیره نشده از یک نمونه مدل ایجاد کنید.
این به ویژه زمانی مفید است که نمونه های مدلی دارید که بسیاری از ویژگی های
مشابه را به اشتراک می گذارند:
$shipping = App\Address::create([ 'type' => 'shipping', 'line_1' => '123 Example Street', 'city' => 'Victorville', 'state' => 'CA', 'postcode' => '90001',]); $billing = $shipping->replicate()->fill([ 'type' => 'billing']); $billing->save();
محدوده های پرس و جو
دامنه های جهانی
دامنه جهانی به شما امکان می دهد برای یک مدل معین، محدودیت هایی را به همه پرس و جوها اضافه کنید. قابلیت حذف نرم لاراول از دامنههای جهانی استفاده میکند تا فقط مدلهای «حذف نشده» را از پایگاه داده بیرون بکشد. نوشتن دامنه های جهانی خود می تواند یک راه راحت و آسان برای اطمینان از اینکه هر پرس و جو برای یک مدل معین محدودیت های خاصی را دریافت می کند، ارائه دهد.
نوشتن دامنه های جهانی
نوشتن یک دامنه جهانی ساده است.
کلاسی را تعریف کنید که
Illuminate\Database\Eloquent\Scope
رابط را پیاده سازی کند.
این رابط به شما نیاز دارد که یک روش را پیاده سازی کنید:
apply
.
این
apply
روش ممکن است
where
در صورت نیاز محدودیت هایی را به پرس و جو اضافه کند:
<?php namespace App\Scopes; use Illuminate\Database\Eloquent\Builder;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Scope; class AgeScope implements Scope{ /** * Apply the scope to a given Eloquent query builder. * * @param \Illuminate\Database\Eloquent\Builder $builder * @param \Illuminate\Database\Eloquent\Model $model * @return void */ public function apply(Builder $builder, Model $model) { $builder->where('age', '>', 200); }}
اگر دامنه جهانی شما ستونهایی را به عبارت انتخابی پرس و جو اضافه میکند، باید
addSelect
به جای استفاده از روش ازselect
. این از جایگزینی ناخواسته عبارت انتخابی موجود در پرس و جو جلوگیری می کند.
کاربرد دامنه های جهانی
برای اختصاص دادن دامنه جهانی به یک مدل، باید
booted
روش یک مدل معین را لغو کنید و از
addGlobalScope
روش استفاده کنید:
<?php namespace App; use App\Scopes\AgeScope;use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * The "booted" method of the model. * * @return void */ protected static function booted() { static::addGlobalScope(new AgeScope); }}
پس از اضافه کردن دامنه، یک پرس و جو به
User::all()
SQL زیر را تولید می کند:
select * from `users` where `age` > 200
دامنه های جهانی ناشناس
Eloquent همچنین به شما امکان میدهد تا با استفاده از Closures، دامنههای جهانی را تعریف کنید، که به ویژه برای دامنههای ساده که کلاس جداگانه را تضمین نمیکنند مفید است:
<?php namespace App; use Illuminate\Database\Eloquent\Builder;use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * The "booted" method of the model. * * @return void */ protected static function booted() { static::addGlobalScope('age', function (Builder $builder) { $builder->where('age', '>', 200); }); }}
حذف دامنه های جهانی
اگر میخواهید یک محدوده جهانی را برای یک پرس و جو حذف کنید، میتوانید از
withoutGlobalScope
روش استفاده کنید.
متد نام کلاس دامنه جهانی را به عنوان تنها آرگومان خود می پذیرد:
User::withoutGlobalScope(AgeScope::class)->get();
یا، اگر دامنه جهانی را با استفاده از بستن تعریف کرده اید:
User::withoutGlobalScope('age')->get();
اگر میخواهید چندین یا حتی همه دامنههای جهانی را حذف کنید، میتوانید از
withoutGlobalScopes
روش زیر استفاده کنید:
// Remove all of the global scopes...User::withoutGlobalScopes()->get(); // Remove some of the global scopes...User::withoutGlobalScopes([ FirstScope::class, SecondScope::class])->get();
محدوده های محلی
دامنههای محلی به شما امکان میدهند مجموعههای مشترکی از محدودیتها را
تعریف کنید که به راحتی میتوانید در سراسر برنامه خود مجدداً از آنها استفاده کنید.
به عنوان مثال، ممکن است لازم باشد مکرراً همه کاربرانی را که "محبوب" در
نظر گرفته می شوند، بازیابی کنید.
برای تعریف یک محدوده، پیشوند یک متد مدل Eloquent را با
scope
.
Scopes همیشه باید یک نمونه سازنده query را برگرداند:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * Scope a query to only include popular users. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopePopular($query) { return $query->where('votes', '>', 100); } /** * Scope a query to only include active users. * * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ public function scopeActive($query) { return $query->where('active', 1); }}
استفاده از یک محدوده محلی
هنگامی که محدوده تعریف شد، می توانید در هنگام پرس و جو از مدل، متدهای
محدوده را فراخوانی کنید.
scope
با این حال، هنگام فراخوانی متد
، نباید پیشوند را وارد کنید .
حتی میتوانید تماسهای زنجیرهای را به حوزههای مختلف زنجیرهای کنید، به
عنوان مثال:
$users = App\User::popular()->active()->orderBy('created_at')->get();
ترکیب چندین محدوده مدل Eloquent از طریق یک
or
عملگر پرس و جو ممکن است نیاز به استفاده از Callbacks Close داشته باشد:
$users = App\User::popular()->orWhere(function (Builder $query) { $query->active();})->get();
با این حال، از آنجایی که این کار می تواند دست و پا گیر باشد، لاراول یک
orWhere
روش "ترتیب بالاتر" را ارائه می دهد که به شما امکان می دهد بدون استفاده از
Closures به راحتی این محدوده ها را به هم متصل کنید:
$users = App\User::popular()->orWhere->active()->get();
دامنه های دینامیک
گاهی اوقات ممکن است بخواهید محدوده ای را تعریف کنید که پارامترها را
بپذیرد.
برای شروع، فقط پارامترهای اضافی خود را به محدوده خود اضافه کنید.
پارامترهای محدوده باید بعد از پارامتر تعریف شوند
$query
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * Scope a query to only include users of a given type. * * @param \Illuminate\Database\Eloquent\Builder $query * @param mixed $type * @return \Illuminate\Database\Eloquent\Builder */ public function scopeOfType($query, $type) { return $query->where('type', $type); }}
اکنون، می توانید هنگام فراخوانی scope پارامترها را ارسال کنید:
$users = App\User::ofType('admin')->get();
مقایسه مدل ها
گاهی اوقات ممکن است لازم باشد تعیین کنید که آیا دو مدل "یکسان" هستند یا
خیر.
این
is
روش ممکن است برای تأیید سریع اتصال دو مدل کلید اولیه، جدول و پایگاه داده
استفاده شود:
if ($post->is($anotherPost)) { //}
مناسبت ها
مدلهای Eloquent چندین رویداد را اجرا میکنند و به شما امکان
میدهند تا به نکات زیر در چرخه عمر یک مدل متصل شوید:
retrieved
,
creating
,
created
,
updating
, ,
updated
,
saving
,
saved
,
deleting
,
deleted
,
restoring
.
restored
رویدادها به شما این امکان را می دهند که هر بار که یک کلاس مدل خاص در
پایگاه داده ذخیره یا به روز می شود، کد را به راحتی اجرا کنید.
هر رویداد نمونه مدل را از طریق سازنده خود دریافت می کند.
این
retrieved
رویداد زمانی فعال می شود که یک مدل موجود از پایگاه داده بازیابی شود.
هنگامی که یک مدل جدید برای اولین بار ذخیره می شود،
creating
و
created
رویدادها فعال می شوند.
هنگامی که یک مدل موجود اصلاح شود و متد فراخوانی شود،
updating
/
رویدادها فعال می شود
.
هنگام ایجاد یا بهروزرسانی یک مدل، رویدادهای / فعال
میشوند
.
updated
save
saving
saved
هنگام صدور بهروزرسانی یا حذف انبوه از طریق Eloquent، رویدادهای
saved
,updated
,deleting
وdeleted
مدل برای مدلهای آسیبدیده فعال نمیشوند. این به این دلیل است که مدل ها در هنگام صدور به روز رسانی یا حذف انبوه هرگز بازیابی نمی شوند.
برای شروع، یک
$dispatchesEvents
ویژگی را در مدل Eloquent خود تعریف کنید که نقاط مختلف چرخه عمر مدل
Eloquent را به
کلاس های رویداد
خود ترسیم می کند :
<?php namespace App; use App\Events\UserDeleted;use App\Events\UserSaved;use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable{ use Notifiable; /** * The event map for the model. * * @var array */ protected $dispatchesEvents = [ 'saved' => UserSaved::class, 'deleted' => UserDeleted::class, ];}
پس از تعریف و ترسیم رویدادهای Eloquent خود، می توانید از شنوندگان رویداد برای مدیریت رویدادها استفاده کنید.
استفاده از بسته ها
بهجای استفاده از کلاسهای رویداد سفارشی، میتوانید بستههایی را ثبت کنید
که هنگام اجرا شدن رویدادهای مدل مختلف اجرا میشوند.
به طور معمول، شما باید این بسته ها را در
booted
روش مدل خود ثبت کنید:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model{ /** * The "booted" method of the model. * * @return void */ protected static function booted() { static::created(function ($user) { // }); }}
ناظران
تعریف ناظران
اگر در حال گوش دادن به بسیاری از رویدادها در یک مدل خاص هستید، می توانید
از ناظران برای گروه بندی همه شنوندگان خود در یک کلاس واحد استفاده کنید.
کلاسهای مشاهدهگر دارای نام روشهایی هستند که رویدادهای Eloquent را که
میخواهید گوش دهید، منعکس میکنند.
هر یک از این روش ها مدل را به عنوان تنها آرگومان خود دریافت می کنند.
دستور
make:observer
Artisan ساده ترین راه برای ایجاد یک کلاس مشاهدهگر جدید است:
php artisan make:observer UserObserver --model=User
این دستور مشاهده گر جدید را در
App/Observers
دایرکتوری شما قرار می دهد.
اگر این دایرکتوری وجود نداشته باشد، Artisan آن را برای شما ایجاد می کند.
مشاهده گر تازه کار شما به شکل زیر خواهد بود:
<?php namespace App\Observers; use App\User; class UserObserver{ /** * Handle the User "created" event. * * @param \App\User $user * @return void */ public function created(User $user) { // } /** * Handle the User "updated" event. * * @param \App\User $user * @return void */ public function updated(User $user) { // } /** * Handle the User "deleted" event. * * @param \App\User $user * @return void */ public function deleted(User $user) { // } /** * Handle the User "forceDeleted" event. * * @param \App\User $user * @return void */ public function forceDeleted(User $user) { // }}
برای ثبت ناظر،
observe
از روش مدلی که می خواهید مشاهده کنید استفاده کنید.
می توانید ناظران را به
boot
روش یکی از ارائه دهندگان خدمات خود ثبت کنید.
در این مثال، مشاهدهگر را در زیر ثبت میکنیم
AppServiceProvider
:
<?php namespace App\Providers; use App\Observers\UserObserver;use App\User;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { User::observe(UserObserver::class); }}
نادیده گرفتن رویدادها
ممکن است گاهی بخواهید به طور موقت همه رویدادهایی که توسط یک مدل اجرا می
شود را "بی صدا" کنید.
شما ممکن است با استفاده از
withoutEvents
روش به این امر برسید.
این
withoutEvents
روش یک Closure را به عنوان تنها آرگومان خود می پذیرد.
هر کدی که در این بسته اجرا شود، رویدادهای مدل را اجرا نخواهد کرد.
برای مثال، موارد زیر یک
App\User
نمونه را بدون شلیک هیچ رویداد مدلی واکشی و حذف میکند.
هر مقداری که با بسته شدن داده شده برگردانده شود با روش زیر برگردانده می
شود
withoutEvents
:
use App\User; $user = User::withoutEvents(function () use () { User::findOrFail(1)->delete(); return User::find(2);});