در استفاده از Accessors, Mutators و Model Events لاراول مراقب باشید!!!

الوکونت لاراول راه های مناسبی برای مدیریت مدل ها را فراهم می کند. به عنوان مثال، accessors و mutators می توانند هر بار در فرمت کردن قبل از بازیابی و ذخیره کردن داده ها
کمک کنند. رویدادها کمک می کنند تا هر زمان که مدل ها اصلاح شوند، برخی اقدامات انجام شود. با این حال، یک چیز است که باید هنگام استفاده از این ابزارها مراقب باشیم.


به attribute های به کار برده شده در متدها دقت کنیم

Accessors

فرض کنید که ما یک جدول به نام users داریم و هر رکورد شامل firstName و lastName است.

mysql> desc users;
+-----------+------------------+
| Field     | Type             |
+-----------+------------------+
| userId    | int(10) unsigned |
| firstName | varchar(255)     |
| lastName  | varchar(255)     |
| birthday  | varchar(8)       |
| age       | int(11)          |
| email     | varchar(255)     |
| password  | varchar(60)      |
| createdAt | timestamp        |
| updatedAt | timestamp        |
+-----------+------------------+

حالا میخوایم نام کامل واسه هر فرد استفاده کنیم ولی نمیخوایم به دیتابیس دست بزنیم. میاییم یک accessor به عنوان یک راه حل فنی به کار بریم:

public function getFullNameAttribute()
{
    return $this->attributes['firstName'] . ' ' . $this->attributes['lastName'];
}

حالا ما به هر وقت خواستیم به ستون fullName که در پایگاه داده وجود ندارد به صورت اتوماتیک نام و نام خانوادگی را بهم میچسباند و به ما تحویل میدهد به صورت زیر:

accessor در لاراول
accessor در لاراول

راه حلی خوب و زیرکانه به نظر میرسد ولی وقتی که ما هر دو ستون یعنی firstName و lastName رو select نکنیم به اررور میخوریم.

اررور در accessor لاراول
اررور در accessor لاراول

این اررور به دلیل اینکه لاراول فقط به داده های که توی $this->attributes وجود دارند و ما انتخاب کرده ایم نگاه میکند، رخ میدهد.


Mutators

مساله بالا در Mutators هم صدق میکند. وقتی یک attribute را ذخیره میکنید مطمعن شوید که انتخاب شده اند.


این بار ما می خواهیم سن هر کاربر را می توان با تاریخ تولد محاسبه کرد. در زیر نشان می دهد که هنگام ذخیره سن، ارزش محاسبه شده بر اساس تاریخ تولد بازگشت خواهد شد. و هنگامی که روز تولد ست نشده باشد، یک خطا برداشته داده خواهد شد. Mutators در اینجا به عنوان راهی برای ذخیره attribute به طور خودکار استفاده می شود.

public function setAgeAttribute($value)
{
    $this->attributes['age'] = Carbon::parse($this->attributes['birthday'])->age;
}
 در لاراول Mutatorstat
در لاراول Mutatorstat

این مثال واقعا خوب نیست از آنجا که mutators فعال نمی شود مگر اینکه attributeها مشخص شود (یعنی سن همان age)، چیزی مانند مثال زیر خیلی گیج کننده خواهد بود برای نوشتن

$user->update(['age'] => 1000) 
// و یا
$user->update(['age'] => '')

اینها فقط برای این هستند تا mutatorها کار کنند.

بنابراین بهترین راه ذخیره سن اینه که هر تولد را ذخیره کنید (به عنوان مثال، mutator برای روز تولد نه ساله). مثال زیر را ببینید. اما به هر حال، این فقط یک مثال برای نشان دادن این است که ما نمی توانیم ویژگی هایی را که در mutatorها انتخاب نکرده ایم استفاده کنیم.

public function setBirthdayAttribute($value)
{
    $this->attributes['birthday'] = $value;
    $this->attributes['age'] = Carbon::parse($value)->age;
}

Model Events

ایونت ها
ایونت ها

همان وضعیت در model event رخ می دهد. با این حال، PHP در این زمان هیچ گونه exception یا خطایی را نمی دهد. هنگامی که ما از ویژگی هایی استفاده می کنیم که قابل دسترسی نیستند مثلا

$user->lastName و یا $user['name']

به جای اررور null برگست داده خواهد شد.

پس، ما فقط باید اطمینان حاصل کنیم که برنامه های ما می توانند با null مقابله کنند. برای معنای events، من فکر می کنم این قابل قبول است زیرا ممکن است نیاز به واکنش مثبت در بعضی از شرایط داشته باشد.


نتیجه:‌ از ابزارها جوری استفاده کنید که برای آن طراحی شده اند

مثالهایی که در بالا توضیح داده شده ممکن است احمقانه باشند. برخی ممکن است فکر کنند که اگر accessors شامل attribute باشد، البته که آنها انتخاب خواهند شد. اما هیچ کس نمی تواند چنین چیزهایی را تضمین کند، به ویژه هنگامی که بیسیک کد بزرگتر و پیچیده تر می شود. علاوه بر این، برای عملکرد sql، ما تمام ستون ها را جستجو نخواهیم کرد، فقط ستون هایی که نیاز داریم. توسعه دهندگان ممكن است متوجه نشوند كه در مدل ها چه اتفاقی می افتد.