نسخه:

الکوئنت: شروع کردن

معرفی

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);
});