Anophel-آنوفل 20 نکته و ترفند Eloquent در لاراول

20 نکته و ترفند Eloquent در لاراول

انتشار:
2

الکونت (Eloquent) یک نگاشت رابطه ای شی (ORM) است که به طور پیش فرض در فریمورک لاراول گنجانده شده است. ORM نرم‌افزاری است که با نمایش داده‌ها به‌عنوان اشیاء، مدیریت سوابق پایگاه‌داده را تسهیل می‌کند و به‌عنوان لایه‌ای از آبسترک در بالای موتور پایگاه داده مورد استفاده برای ذخیره داده‌های یک برنامه کاربردی کار می‌کند.


Eloquent کار تعامل با جداول پایگاه داده را تسهیل می کند، یک رویکرد شی گرا برای ایجاد، به روز رسانی، و حذف رکوردهای پایگاه داده ارائه می دهد، در حالی که یک رابط ساده برای اجرای کوئری های SQL پیچیده را نیز فراهم می کند.

بیاید با هم دیگر در آنوفل با 20 تا از مهمترین الکونت های لاراول آشنا شویم. اگر با لاراول 11 آشنا نیستید از طریق این مقاله می توانید با لاراول 11 اشنا شوید.

20 تا از مهم ترین متد های الکونت در لاراول

ORM گویا مکانیزمی ساده به نظر می رسد، اما در زیر هود، بسیاری از عملکردهای نیمه پنهان و راه های کمتر شناخته شده برای دستیابی به چیزهای بیشتر با آن وجود دارد. برای آشنایی با کد نویسی تمیز در لاراول نیز می توانید این مقاله را بررسی کنید.

1. افزایش و کاهش

به جای این:

$article = Article::find($article_id);
$article->read_count++;
$article->save();

شما می توانید این کار را انجام دهید:

$article = Article::find($article_id);
$article->increment('read_count');

همچنین کد زیر نیز:

Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // +10
Product::find($produce_id)->decrement('stock'); // -1

2. متد های XorY

Eloquent متد های کمی دارد که دو متد را ترکیب کند، مانند "لطفا X را انجام دهید، در غیر این صورت Y را انجام دهید".

مثال 1 : ()findOrFail:

بجای کد زیر:

$user = User::find($id);
if (!$user) { abort (404); }

این کار را انجام دهید:

$user = User::findOrFail($id);

مثال 2 : ()firstOrCreate:

بجای کد زیر:

$user = User::where('email', $email)->first();
if (!$user) {
  User::create([
    'email' => $email
  ]);
}

فقط این کار را انجام دهید:

$user = User::firstOrCreate(['email' => $email]);

برای آشنایی با 20 ترفند و نکات مهم در لاراول در سال 2024 این مقاله را بررسی کنید.

آیا با توسعه تست محور در لاراول آشنا هستید، اگر نیستید این مقاله را بررسی کنید.

3. متد ()boot در مدل

یک متد جادویی به نام ()boot در مدل Eloquent وجود دارد که می توانید رفتار پیش فرض را لغو کنید:

class User extends Model
{
    public static function boot()
    {
        parent::boot();
        static::updating(function($model)
        {
            // do some logging
            // override some property like $model->something = transform($something);
        });
    }
}

احتمالاً یکی از محبوب‌ترین مثال‌ها تنظیم مقدار فیلد در لحظه ایجاد شی مدل است. فرض کنید می خواهید فیلد UUID را در آن لحظه ایجاد کنید.

public static function boot()
{
  parent::boot();
  self::creating(function ($model) {
    $model->uuid = (string)Uuid::generate();
  });
}

4. روابط با شرایط و سفارشی

این یک روش معمولی برای تعریف روابط است. اگر با روابط در لاراول آشنا نیستید این مقاله را بررسی کنید.

public function users() {
    return $this->hasMany('App\User');
}

اما آیا می دانستید که در این مرحله ما می توانیم Where یا orderBy را اضافه کنیم؟ به عنوان مثال، اگر می خواهید یک رابطه خاص برای برخی از انواع کاربران، همچنین از طریق ایمیل سفارش داده شود، می توانید این کار را انجام دهید:

public function approvedUsers() {
    return $this->hasMany('App\User')->where('approved', 1)->orderBy('email');
}

5. ویژگی های مدل: timestamps، ضمیمه ها و غیره

چند "پارامتر" از یک مدل Eloquent به شکل ویژگی های آن کلاس وجود دارد. احتمالاً محبوب ترین آنها عبارتند از:

class User extends Model {
    protected $table = 'users';
    protected $fillable = ['email', 'password']; // which fields can be filled with User::create()
    protected $dates = ['created_at', 'deleted_at']; // which fields will be Carbon-ized
    protected $appends = ['field1', 'field2']; // additional values returned in JSON
}

اما صبر کنید، موارد بیشتری وجود دارد:

protected $primaryKey = 'uuid'; // it doesn't have to be "id"
public $incrementing = false; // and it doesn't even have to be auto-incrementing!
protected $perPage = 25; // Yes, you can override pagination count PER MODEL (default 15)
const CREATED_AT = 'created_at';
const UPDATED_AT = 'updated_at'; // Yes, even those names can be overridden
public $timestamps = false; // or even not used at all

و حتی موارد بیشتری نیز وجود دارد، من جالب‌ترین آنها را فهرست کرده‌ام، برای اطلاعات بیشتر لطفاً کد کلاس مدل آبسترک پیش‌فرض را بررسی کنید و تمام ویژگی‌های استفاده شده را بررسی کنید.

برای آشنایی با مهم ترین ترفند ها و روش ها در لاراول Restful API این مقاله را بررسی کنید.

آیا با تزریق وابستگی در لاراول آشنا هستید؟ اگر نیستید این مقاله می تواند برای شما مفید باشد.

6. ورودی های متعدد را پیدا کنید

همه متد ()find را می شناسند، درست است؟

$user = User::find(1);

من کاملا متعجبم که چند نفر از این موضوع می دانند که می تواند چندین ID را به عنوان یک آرایه بپذیرد:

$users = User::find([1,2,3]);

7. الکونت WhereX

یک راه زیبا برای تبدیل این کد وجود دارد:

$users = User::where('approved', 1)->get();

به این کد:

$users = User::whereApproved(1)->get()

بله، می توانید نام هر فیلدی را تغییر دهید و آن را به عنوان پسوند به "where" اضافه کنید و با مجیک کار می کند.

همچنین چند متد از پیش تعریف شده در Eloquent مربوط به تاریخ/زمان وجود دارد:

User::whereDate('created_at', date('Y-m-d'));
User::whereDay('created_at', date('d'));
User::whereMonth('created_at', date('m'));
User::whereYear('created_at', date('Y'));

8. ترتیب بر اساس روابط

یک "ترفند" کمی پیچیده تر. اگر موضوعات فروم دارید اما می خواهید آنها را با آخرین پست سفارش دهید چه؟ نیاز بسیار رایج در انجمن ها با آخرین موضوعات به روز شده در بالا، درست است؟

ابتدا، یک رابطه جداگانه برای آخرین پست در مورد موضوع :

public function latestPost()
{
    return $this->hasOne(\App\Post::class)->latest();
}

و سپس، در کنترلر خود، می توانیم این "مجیک" را انجام دهیم:

$users = Topic::with('latestPost')->get()->sortByDesc('latestPost.created_at');

برای آشنایی با هنر اعتبار سنجی در لاراول این مقاله را بررسی کنید.

9. ()Eloquent::when، دیگر if-else’s نیست

بسیاری از ما کوئری های شرطی را با "if-else" می نویسیم، چیزی شبیه به این:

if (request('filter_by') == 'likes') {
    $query->where('likes', '>', request('likes_amount', 0));
}
if (request('filter_by') == 'date') {
    $query->orderBy('created_at', request('ordering_rule', 'desc'));
}

اما راه بهتری وجود دارد – استفاده از ()When:

$query = Author::query();
$query->when(request('filter_by') == 'likes', function ($q) {
    return $q->where('likes', '>', request('likes_amount', 0));
});
$query->when(request('filter_by') == 'date', function ($q) {
    return $q->orderBy('created_at', request('ordering_rule', 'desc'));
});

ممکن است کوتاه‌تر یا ظریف‌تر به نظر نرسد، اما قدرتمندترین آن عبور از پارامترها است:

$query = User::query();
$query->when(request('role', false), function ($q, $role) {
    return $q->where('role_id', $role);
});
$authors = $query->get();

آیا با لاراول Octane آشنا هستید این مقاله را بررسی کنید.

10.  رابطه BelongsTo مدل های پیش فرض

فرض کنید پست متعلق به نویسنده و سپس کد Blade دارید:

{{ $post->author->name }}

اما اگر نویسنده حذف شود، یا به دلایلی تنظیم نشده باشد، چه؟ شما یک خطا دریافت خواهید کرد، چیزی مانند "property of non-object".

البته می توانید از این طریق جلوگیری کنید:

{{ $post->author->name ?? '' }}

اما می توانید این کار را در سطح رابطه Eloquent انجام دهید:

public function author()
{
    return $this->belongsTo('App\Author')->withDefault();
}

در این مثال، رابطه ()author یک مدل خالی App\Author را برمی‌گرداند اگر هیچ نویسنده‌ای به پست ضمیمه نشده باشد.

علاوه بر این، می‌توانیم مقادیر ویژگی پیش‌فرض را به آن مدل پیش‌فرض اختصاص دهیم.

public function author()
{
    return $this->belongsTo('App\Author')->withDefault([
        'name' => 'Guest Author'
    ]);
}

11. سفارش توسط Mutator

تصور کنید این کد را دارید:

function getFullNameAttribute()
{
  return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}

حالا، می‌خواهید با آن full_name سفارش دهید؟ این کد زیر کار نخواهد کرد:

$clients = Client::orderBy('full_name')->get(); // doesn't work

راه حل کاملا ساده است. پس از دریافت نتایج باید سفارش دهیم.

$clients = Client::get()->sortBy('full_name'); // works!

توجه داشته باشید که نام تابع متفاوت است، orderBy نیست، sortBy است.

12. ترتیب پیش فرض در اسکوپ گلوبال

اگر بخواهید که ()User::all همیشه بر اساس فیلد name مرتب شود چه؟ شما می توانید یک اسکوپ گلوبال اختصاص دهید. بیایید به متد ()boot که قبلاً در بالا به آن اشاره کردیم برگردیم.

protected static function boot()
{
    parent::boot();
 
    // Order by name ASC
    static::addGlobalScope('order', function (Builder $builder) {
        $builder->orderBy('name', 'asc');
    });
}

13. متد های کوئری خام

گاهی لازم است کوئری های خام را به عبارات Eloquent خود اضافه کنیم. خوشبختانه، توابعی برای آن وجود دارد.

// whereRaw
$orders = DB::table('orders')
    ->whereRaw('price > IF(state = "TX", ?, 100)', [200])
    ->get();
 
// havingRaw
Product::groupBy('category_id')->havingRaw('COUNT(*) > 1')->get();
 
// orderByRaw
User::where('created_at', '>', '2016-01-01')
  ->orderByRaw('(updated_at - created_at) desc')
  ->get();

14. Replicate: یک کپی از یک ردیف بسازید

این یکی کوتاه است. بدون توضیح عمیق، در اینجا بهترین راه برای کپی کردن ورودی پایگاه داده وجود دارد:

$task = Tasks::find(1);
$newTask = $task->replicate();
$newTask->save();

15. متد ()Chunk برای جداول بزرگ

دقیقاً مربوط به Eloquent نیست، بیشتر درباره Collection است، اما همچنان قدرتمند است، برای پردازش مجموعه داده های بزرگتر، می توانید آنها را به قطعات تکه تکه کنید.


بجای کد زیر:

$users = User::all();
foreach ($users as $user) {
    // ...

شما می توانید این کد را بنویسید:

User::chunk(100, function ($users) {
    foreach ($users as $user) {
        // ...
    }
});

16. هنگام ایجاد یک مدل چیزهای اضافی ایجاد کنید

همه ما این دستور Artisan را می دانیم:

php artisan make:model Company

اما آیا می دانید سه فلگ مفید برای تولید فایل های مرتبط با مدل وجود دارد؟

php artisan make:model Company -mcr
  1. m- یک فایل مایگرشن ایجاد می کند

  2. c -یک کنترلر ایجاد می کند

  3. r- نشان خواهد داد که کنترلر باید resourceful باشد

17. هنگام ذخیره، updated_at را لغو کنید

آیا می دانستید که متد ()save<- می تواند پارامترها را بپذیرد؟ در نتیجه، می‌توانیم به آن بگوییم که متد پیش‌فرض updated_at را نادیده بگیرد تا با تایم زمانی فعلی پر شود. 

این را ببینید:

$product = Product::find($id);
$product->updated_at = '2019-01-01 10:00:00';
$product->save(['timestamps' => false]);

در اینجا ما پیش‌فرض updated_at را با نسخه از پیش تعریف‌شده خود لغو می‌کنیم.

18. نتیجه یک ()update چیست؟

آیا تا به حال فکر کرده اید که این کد در واقع چه چیزی را برمی گرداند؟

$result = $products->whereNull('category_id')->update(['category_id' => 2]);

منظورم این است که به روز رسانی در پایگاه داده انجام می شود، اما نتیجه result$ چه چیزی را شامل می شود؟


پاسخ ردیف های تحت تاثیر قرار می گیرد. بنابراین اگر باید بررسی کنید که چند ردیف تحت تأثیر قرار گرفته اند، نیازی نیست چیز دیگری را فراخوانی کنید - متد ()update این شماره را برای شما برمی گرداند.

19. براکت ها را به یک کوئری Eloquent تبدیل کنید

اگر کوئریی SQL خود را داشته باشید و یا مخلوط کنید، مانند این، چه اتفاقی می‌افتد:

... WHERE (gender = 'Male' and age >= 18) or (gender = 'Female' and age >= 65)

چگونه آن را به Eloquent ترجمه کنیم؟ این راه اشتباه است:

$q->where('gender', 'Male');
$q->orWhere('age', '>=', 18);
$q->where('gender', 'Female');
$q->orWhere('age', '>=', 65);

ترتیب نادرست خواهد بود. راه درست کمی پیچیده تر است، با استفاده از closure functions به عنوان کوئری های فرعی:

$q->where(function ($query) {
    $query->where('gender', 'Male')
        ->where('age', '>=', 18);
})->orWhere(function($query) {
    $query->where('gender', 'Female')
        ->where('age', '>=', 65);
})

20. orWhere با چند پارامتر

در نهایت، می‌توانید آرایه‌ای از پارامترها را به ()orWhere ارسال کنید. متد "معمول":

$q->where('a', 1);
$q->orWhere('b', 2);
$q->orWhere('c', 3);

شما می توانید این کار را به این صورت انجام دهید:

$q->where('a', 1);
$q->orWhere(['b' => 2, 'c' => 3]);

نتیجه

Eloquent یک ORM قدرتمند است که با چارچوب لاراول ساخته شده است. بسیاری از کوئری های پیچیده‌ای را که برای مقابله با روابط، ایجاد، به‌روزرسانی، و حذف رکوردهای پایگاه داده و جستجو، فیلتر کردن و محدود کردن نتایج کوئری ضروری هستند، خلاصه می‌کند. اگر متد الکونت دیگری می شناسید که بسیار پر کاربرد است ولی در اینجا به آن اشاره نشده است در قسمت نظرات آن را با ما به اشتراک بگذارید.

#لاراول#الکونت#لاراول_الکونت#laravel#laravel_elequent#clean_code_laravel
نظرات ارزشمند شما :

در حال دریافت...

مقاله های مشابه

در حال دریافت...