لطفا صبر کنید ...

کش کردن مدل‌ها در لاراول

الهه قنبری

توسط الهه قنبری

مدیر
دیدگاه ها: 0
بازدید ها : 97
رایگان
هدف ما این است که شما، در بالاترین سطح طراحی و توسعه وب باشید.

ثبت نام کنید

ممکن است قبلا برخی از داده‌های مدل خود را در کنترلر کش کرده باشید، اما در این مقاله از لیداوب، تکنیک کش کردن داده‌ها در مدل‌ها را به شما نشان می‌دهیم که بتوانید به داده‌های خود سریع‌تر دسترسی داشته باشید.


با استفاده از یک کلید کش منحصر به فرد در مدل، شما می‌توانید خصوصیات و ویژگی‌های مدل‌های لاراول خود را که به صورت خودکار در زمان بروز رسانی مدل (یا مدل‌های مرتبط) آپدیت می‌شوند، کش کنید. مزیت اصلی این روش در این است که دسترسی به داده‌های کش شده در مدل، سریع‌تر از دسترسی به داده‌های کش شده در کنترلر است.

تکنیک کش کردن مدل‌ها در لاراول

فرض کنید، شما یک مدل Article دارید که دارای چند مدل‌ Comment مرتبط است. با توجه به قالب blade لاراول زیر، می‌توانید تعداد نظرات را مانند مثال زیر در مسیر /article/:id بازیابی کنید:

$article->comments->count() {{ str_plural('Comment', $article->comments->count())

شما می‌توانید تعداد نظرات را در کنترلر خود کش کنید، ولی زمانی که کنترلر شما دارای چندین پرس و جو و اطلاعات زیادی باشد که نیاز به کش شدن دارند، این کار زیاد جالب نخواهد بود. همچنین، در کنترلر، دسترسی به داده‌های کش شده سریع نخواهد بود.

می‌توانیم قالبی بسازیم که وقتی مقاله آپدیت می‌شود، با دیتابیس ارتباط برقرار کند. در این صورت، هر کدی که به مدل دسترسی داشته باشد، می‌تواند مقدار کش شده را به دست آورد:

$article->cached_comments_count {{ str_plural('Comment', $article->cached_comments_count)

توسط model accessor، می‌توان تعداد نظرات را براساس آخرین باری که مقاله آپدیت می‌شود، کش کرد.

اما زمانی که یک نظر جدید اضافه یا حذف می‌شود، چگونه می‌توان ستون update_at مقاله را آپدیت کرد؟ با استفاده از متد touch() می‌توان این کار را انجام داد.

مدل‌های Touching

توسط متد touch() مدل، می‌توانیم ستون update_at مقاله را آپدیت کنیم:

$ php artisan tinker
>>> $article = \App\Article::first();
=> App\Article {#746
id: 1,
title: "Hello World",
body: "The Body",
created_at: "2018-01-11 05:16:51",
updated_at: "2018-01-11 05:51:07",
}
>>> $article->updated_at->timestamp
=> 1515649867
>>> $article->touch();
=> true
>>> $article->updated_at->timestamp
=> 1515650910

می‌توانیم از زمان بندی آپدیت برای باطل کردن حافظه کش استفاده کنیم، ولی زمانی که بخواهیم نظری را اضافه یا حذف کنیم، چگونه می‌توانیم فیلد updated_at مقاله را آپدیت کنیم؟

اگر مدل‌های Eloquent دارای ویژگی $touches باشند، می‌توان این کار را انجام داد. در اینجا، مدل comment را مشاهده می‌کنید:

<?php

namespace App;

use App\Article;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
protected $guarded = [];

protected $touches = ['article'];

public function article()
{
return $this->belongsTo(Article::class);
}

}

ویژگی $touches یک آرایه است که وقتی یک نظر ایجاد، ذخیره یا حذف می‌شود، مورد استفاده قرار می‌گیرد.

صفات کش شده

حالا اکسسور $ article-> cached_comments_count را در نظر می‌گیریم. پیاده سازی آن در مدل App \ Article می‌تواند به صورت زیر باشد:

public function getCachedCommentsCountAttribute()
{
return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
return $this->comments->count();
});
}

ما مدل را برای مدت پانزده دقیقه و با استفاده از متد cacheKey() منحصر به فرد کش می‌کنیم و می‌توانیم به راحتی تعداد نظرات را از تابع closure بر‌گردانیم. توجه کنید که ما همچنین می‌توانیم از متد Cache :: rememberForever() نیز جهت حذف کلیدهای غیر مجاز استفاده کنیم.

متدcacheKey() باید مدل را منحصر به فرد کند، یعنی هنگامی که مدل آپدیت می‌شود، حافظه پنهان نامعتبر می‌شود. در اینجا، پیاده سازی cacheKey را مشاهده می‌کنید:

public function cacheKey()
{
return sprintf(
"%s/%s-%s",
$this->getTable(),
$this->getKey(),
$this->updated_at->timestamp
);
}

خروجی این مثال برای متد cacheKey() مدل می‌تواند نمایش رشته‌ای زیر را برگرداند:

articles/1-1515650910

این کلید شامل نام جدول، شناسه مدل و زمان بندی فعلی update_at است. زمانی که ما مدل را touch می‌کنیم، نشانگر زمان آپدیت می‌شود و کش مدل ما نامعتبر خواهد شد.

در اینجا، مدل Article را مشاهده می‌کنید:

<?php

namespace App;

use App\Comment;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
public function cacheKey()
{
return sprintf(
"%s/%s-%s",
$this->getTable(),
$this->getKey(),
$this->updated_at->timestamp
);
}

public function comments()
{
return $this->hasMany(Comment::class);
}

public function getCachedCommentsCountAttribute()
{
return Cache::remember($this->cacheKey() . ':comments_count', 15, function () {
return $this->comments->count();
});
}
}

و مدل Comment مرتبط:

<?php

namespace App;

use App\Article;
use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
protected $guarded = [];

protected $touches = ['article'];

public function article()
{
return $this->belongsTo(Article::class);
}
}

 تا اینجا، مشاهده کردید که چگونه می‌توان یک نظر ساده را کش کرد، اما اگر بخواهیم تمام نظرات را کش کنیم، چطور؟

public function getCachedCommentsAttribute()
{
return Cache::remember($this->cacheKey() . ':comments', 15, function () {
return $this->comments;
});
}

شما همچنین می‌توانید به جای سریال سازی مدل‌ها، نظرات را به آرایه تبدیل کنید که امکان دسترسی ساده آرایه به داده‌ها را در بخش فرانت اند می‌دهد:

public function getCachedCommentsAttribute()
{
return Cache::remember($this->cacheKey() . ':comments', 15, function () {
return $this->comments->toArray();
});
}

ما متد cacheKey() را در مدل Article تعریف کردیم، اما در صورت تمایل می‌توانید این متد را از طریق صفتی به نام ProvidesModelCacheKey تعریف کنید که می‌توانید از آن در چند مدل استفاده کنید یا متد را در مدل پایه‌ای که مدل‌های دیگر را گسترش می‌دهد، تعریف کنید. شما حتی می‌توانید از یک کنتراکت یا رابط برای مدل‌هایی که متد cacheKey() را پیاده سازی می‌کنند، استفاده کنید.

دوره‌های آموزشی در لیداوب:

آموزش پایه لاراول

آموزش CSS

آموزش HTML مقدماتی

برای مطالعه جدیدترین مقالات کاربردی لاراول، می‌توانید کتابخانه آنلاین لیداوب را دنبال کنید.

منبع :

5 از 1 رای

 مطالب مرتبط  

در قسمت زیر مطالبی وجود دارند که با مقاله فعلی مرتبط هستند

متاسفانه فقط اعضای سایت قادر به ثبت دیدگاه هستند

برترین های