المعدلات في رابط الكائنات بالعلاقات Eloquent

من موسوعة حسوب
مراجعة 13:47، 23 أكتوبر 2018 بواسطة رؤيا-بنعطية (نقاش | مساهمات)
(فرق) → مراجعة أقدم | المراجعة الحالية (فرق) | مراجعة أحدث ← (فرق)

مقدمة

تمكّنك المعدّلات والموصّلات من تنسيق قيم خاصيّات Eloquent عند استردادها أو تعيينها على كائنات النماذج. مثلًا، يمكنك استخدام مشفّر Laravel لتشفير قيمة ما أثناء تخزينها بقاعدة لًا، ومن ثمّ فك تشفيرها تلقائيًّا عند استردادها من نموذج Eloquent.

إضافةً إلى المعدلات والموصلات الافتراضية، يمكّنك Eloquent من التحويل التلقائي للخاصيات الزمنية إلى كائنات من الصنف Carbon أو حتى تحويل الخاصيات النصية إلى كائنات JSON.

المعدلات والموصلات

تعريف الموصل

لتعريف موصل ما، عرف التابع getFooAttribute على صنف نموذجك حيث Foo هو اسم الحقل المراد الوصول إليه (بعد تحويل صيغة الاسم إلى PascalCase). في هذا المثال، سنعرف موصل للحقل first_name. سيُستدعى الموصل تلقائيًّا من قبل Eloquent عند استرداد قيمة الحقل first_name:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   /**
    * قراءة الاسم الأول للمستخدم..
    *
    * @param  string $value
    * @return string
    */
   public function getFirstNameAttribute($value)
   {
       return ucfirst($value);
   }
}

كما نرى، تُمرّر القيمة الافتراضية للحقل إلى تابع الموصل، مما يتيح لك تعديل هذه القيمة. للوصول إلى القيمة المعدلة من قبل الموصل، قم بالوصول إلى الخاصية first_name على نموذجك:

$user = App\User::find(1);

$firstName = $user->first_name;

وبالطبع، يمكنك استخدام الموصلات لإنشاء قيم جديدة ومحسوبة تلقائيًّا من القيم الموجودة مسبقًا:

/**
* قراءة الاسم الكامل للمستخدم..
*
* @return string
*/
public function getFullNameAttribute()
{
   return "{$this->first_name} {$this->last_name}";
}

تعريف المعدل

لتعريف معدل ما، عرف التابع setFooAttribute على صنف نموذجك حيث Foo هو اسم الحقل المراد التعديل عليه (بعد تحويل صيغة الاسم إلى PascalCase). لذلك مجددًا، سنعرف معدل للحقل first_name. سيُستدعى المعدل تلقائيًّا من قبل Eloquent عند تعيين قيمة الحقل first_name:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   /**
    * تعيين الاسم الأول للمستخدم.
    *
    * @param  string $value
    * @return void
    */
   public function setFirstNameAttribute($value)
   {
       $this->attributes['first_name'] = strtolower($value);
   }
}

يتلقى المعدل القيمة المراد تعيينها على الخاصية، مما يتيح لك تعديل هذه القيمة وتعيينها على الخاصية attributes الداخلية لنماذج Eloquent. مثلاً، إذا أردنا تعيين الاسم الأول ليصبح Sally:

$user = App\User::find(1);

$user->first_name = 'Sally';

في هذا المثال، سيُستدعى التابع setFirstNameAttribute وتُمرّر القيمة Sally له. سيطبّق المعدل بعد ذلك التابع strtolower للاسم ويعيّنه للحقل.

المعدلات الزمنية

يحوّل Eloquent افتراضيًّا الحقلين created_at و updated_at لكائنات من النوع Carbon، الذي يرث من الصنف الداخلي DateTime الخاص بـ PHP لتزويد مجموعة من التوابع المساعدة. يمكنك تخصيص الحقول الزمنية التي تُعدّل، أو إلغاء التعديل بأكمله، عن طريق إعادة تعيين الخاصية dates على نموذجك:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   /**
    * الخاصيات التي يجب تحويلها إلى كائنات زمنية.
    *
    * @var array
    */
   protected $dates = [
       'created_at',
       'updated_at',
       'deleted_at'
   ];
}

عند اعتبار حقل ما زمنيًّا، يمكنك تعيين قيمته إلى طابع زمني UNIX، أو نص تاريخ (Y-m-d)، أو كائن من النوع DateTime أو Carbon؛ وستُخزّن القيمة الزمنية تلقائيًّا وبشكل صحيح في قاعدة البيانات:

$user = App\User::find(1);

$user->deleted_at = now();

$user->save();

كما ذُكر آنفًا، عند استرداد القيم الموجودة في مصفوفة dates، ستُحوّل تلقائيًّا إلى كائن من نوع Carbon، مما يتيح لك استخدام أي من توابع Carbon على هذه الحقول:

$user = App\User::find(1);

return $user->deleted_at->getTimestamp();

تنسيق الحقول الزمنية

تُنسّق الحقول الزمنية افتراضيًّا بالنمط 'Y-m-d H:i:s'. إذا أردت تخصيص هذا النمط، عيّن الخاصية dateFormat على نموذجك. تحدد هذه الخاصية كيفية تخزين القيم الزمنية في قاعدة بياناتك، وكيفية تنسيق هذه القيم عند سلسلتها إلى مصفوفة أو كائن JSON:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Flight extends Model
{
   /**
    * نمط تخزين الحقول الزمنية.
    *
    * @var string
    */
   protected $dateFormat = 'U';
}

تحويل الحقول

تزوّد الخاصية casts في نموذجك بتابع مساعد لتحويل الحقول إلى أنواع بيانات معروفة. يجب أن تكون الخاصية casts مصفوفة، تكون المفاتيح فيها أسماء الحقول التي ستُحوّل، والقيم أنواع البيانات التي تُحوّل إليها. إن التحويلات المتاحة هي: integer, real, float, double, string, boolean, object, array, collection, date, datetime, و timestamp.

لنحوّل على سبيل المثال الحقل is_admin، الذي يُخزن في قاعدة البيانات كقيمة صحيحة (0 أو 1)، إلى قيمة منطقية boolean:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   /**
    * الحقول التي يجب تحويلها.
    *
    * @var array
    */
   protected $casts = [
       'is_admin' => 'boolean',
   ];
}

الآن، سيُحوّل الحقل is_admin تلقائيًّا إلى قيمة منطقية عند الوصول إليها، حتى ولو كان نمط تخزينها في قاعدة البيانات قيمة صحيحة:

$user = App\User::find(1);

if ($user->is_admin) {

  //

}

تحويلات المصفوفات وكائنات JSON

يساعد نمط التحويل array بشكل خاص عند العمل مع الحقول التي تُخزّن القيم المسلسلة كـ JSON فيها. مثلاً، إذا احتوت قاعدة بياناتك على حقل من النوع JSON أو TEXT يحتوي على كائن JSON مسلسل، عند إضافة التحويل array إلى ذلك الحقل، ستُفكّ السلسلة تلقائيًّا إلى مصفوفة PHP عند الوصول إلى هذا الحقل على نموذج Eloquent:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   /**
    * الحقول التي يجب تحويلها.
    *
    * @var array
    */
   protected $casts = [
       'options' => 'array',
   ];
}

بعد تعريف التحويل، يمكنك الوصول إلى الحقل options وستُفكّ السلسلة تلقائيًّا من JSON إلى مصفوفة PHP. عند تعيين قيم الحقل options، ستُحوّل المصفوفة المعطاة تلقائيًّا إلى كائن JSON مسلسل وذلك للتخزين:

$user = App\User::find(1);

$options = $user->options;

$options['key'] = 'value';

$user->options = $options;

$user->save();

تحويلات الأزمان

عند استخدام نمط التحويل date أو datetime، يمكنك تعيين النمط الزمني. سيُستخدم هذا النمط عند سلسلة السجل إلى مصفوفة أو كائن JSON:

/**
* الحقول التي يجب تحويلها.
*
* @var array
*/
protected $casts = [
   'created_at' => 'datetime:Y-m-d',
];

مصادر