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

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

استفاده از Eloquent ها میتواند در طراحی و برنامه نویسی بسیار کمک کند. در این مقاله سعی شده نکات Eloquent  را که با عنوان های   ۲۰ نکته و ترفند درباره Eloquent در لاراول   یا    ۶ ترفند Eloquent که هر توسعه دهنده laravel باید بداند  و …. مطرح شده ، گردآوری و توضیح داده شود.

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

 

۱ – افزایش و کاهش ( Increments and Decrements  )

به جای این:

$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

 

۲ – متد های X یا Y

Eloquent دارای چندین فانکشن‌ ( functions ) است که دو متد را ترکیب می کند ، مانند “لطفا X را انجام بده ، در غیر این صورت Y را انجام بده”.

مثال ۱ – findOrFail() :

بجای این کار :

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


 

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

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

 

مثال ۲ –  firstOrCreate()  :

 

بجای این کار :

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


 

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

 

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

 

 

۳ – متد Model boot()

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

 

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


 

احتمالاً یکی از محبوب‌ترین نمونه‌ها تعیین مقدار فیلد در زمان ساخت model object است. بیایید بگوییم که شما در آن لحظه می‌خواهید فیلدUUID را تولید کنید.

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


 

۴- ارتباط با شرایط و ترتیب

این یک روش معمول برای تعریف رابطه است:

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

 

اما آیا می دانید در این مرحله می توانیم where یا orderBy را اضافه کنیم؟

برای مثال ، اگر تو میخوای یه رابطه خاصی برای بعضی از کاربران داشته باشی ، میتوانی با ایمیل آنهارا مرتب کنی، برای اینکار :

 

 

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


 

۵-  ویژگی‌های مدل: timestamp ها ،append ها و …

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

 

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

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

 

۶- پیدا کردن چند ورودی

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

$user = User::find(1);

من خیلی تعجب کردم که چطور تعداد کمی از این موضوع آگاه هستند که این دستور می‌توان چند آیدی را به عنوان یک آرایه بپذیرند:

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

 

۷- Where X

یک روش زیبا برای برگرداندن وجود دارد:

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

در این مورد:

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

بله می‌توانید نام هر فیلد را تغییر دهید و آن را به عنوان suffix ( پسوند ) به 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'));

 

۸- مرتب‌ کردن بر اساس رابطه

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

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

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

 

و سپس، در controller مان، می‌توانیم این جادو را انجام دهیم:

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

 

۹- استفاده از when() در مبحث Eloquent  ، دیگر 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();

 

۱۰- BelongsTo پیش‌فرض مدل‌ها

بیایید بگوییم که شما پستی دارید که متعلق به نویسنده است و سپس کد Blade  آن :

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

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

البته، شما می‌ توانید از  این جلوگیری کنید ، مثل این:

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

اما شما می‌ توانید آن را در سطح Eloquent relationship انجام دهید:

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

 

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

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

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

 

۱۱- مرتب سازی به وسیله 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!

توجه کنید که نام فانکشن متفاوت است ، order By نشده ، sortBy شده است.

 

۱۲ – مرتب سازی پیش‌‌ فرض در global scope

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

protected static function boot()
{
    parent::boot();

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

 

اطلاعات بیشتر درمورد Query Scope ها را بخوانید.

 

۱۳ – متدهای کوئری خام ( Raw query  )

بعضی اوقات ما نیاز به اضافه کردن نمایش داده‌ های خام به Eloquent statement های خود داریم. خوشبختانه، فانکشن‌ هایی برای آن وجود دارد.

// 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();

 

۱۴- تکرار: یک کپی از یک سطر ایجاد کنید

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

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

 

 

 

 

منبع laravel-news.com

1+

در شبکه های اجتماعی
نظرات کاربران

دیدگاهتان را بنویسید

شما میتوانید برای وارد کردن لینک و کدهایHTML از تگ های زیر استفاده کنید : <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>