فصل ۱۲-۴: آشنایی با اضافه، حذف و بروزرسانی داده‌ها در روابط بین جداول

06 آبان 1397
درسنامه درس 18 از سری لاراول
Laravel-Main-crud

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

ذخیره ، بروزرسانی و حذف در روابط یک به چند

برای مقدمه با یک مثال شروع می‌کنیم. فرض کنید شما دو جدول به نام‌های posts و comments دارید. به ازای هر پست چندین کامنت وجود دارد و بنابراین یک رابطه‌ی یک به چند ایجاد می‌شود. حال یک کلید خارجی در جدول comments حضور خواهد داشت که با ستون post_id مشخص شده است که این کلید اجباری است و مقدار null‌ نمی‌پذیرد. بنابراین برای ذخیره‌ی یا حذف یا بروزرسانی یک نظر هموراه باید id آن پست به صورت خودکار به ستون اضافه شود.

Eloquent ابزار و متدی را جهت ذخیره‌سازی یک مدل جدید یا به عبارتی یک رکورد جدید در اختیار ما قرار می‌دهد. این متد save نام دارد. فرض کنید می‌خواهیم یک رکورد جدید در جدول comments ثبت کنیم. بنابراین داریم:

$comment = new App\Comment(['message' => 'A new comment.']);

$post = App\Post::find(1);

$post->comments()->save($comment);

با این اجرای دستورهای فوق یک مدل جدید به نام comment می‌سازیم. سپس post موردنظر را با متد find پیدا می‌کنیم و در نهایت برای متد comments که در مدل Post.php تعریف شده است از دستور save استفاده کرده و مقدار متغییر comment$‌ را به عنوان آرگومان ورودی به آن ارسال خواهیم کرد.

همچنین برای ذخیره سازی تعداد بیشتری از نظرات می‌توان از متد saveMany استفاده کرد:

$post = App\Post::find(1);

$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);

متد create

این متد دقیقا مشابه متد save و saveMany می‌باشد با این تفاوت که متد create آرایه خام PHP را هم به عنوان ورودی می‌پذیرد ولی متدهای save , saveMany همواره یک نمونه‌ی کامل از شیء Eloquent را دریافت می‌کنند:

$post = App\Post::find(1);

$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);

در نظر داشته باشید که قبل از استفاده متد create باید همواره از صفت mass assignment در مدل خود استفاده کرده باشید. برای آگاهی از این صفت مقاله زیر را مطالعه بفرمایید:

روابط BelongsTo

هنگامیکه یک رابطه‌ی belongsTo بروزرسانی می‌شود، باید و باید از متد associate استفاده شود. این متد یک کلید خارجی در مدل فرزند تنظیم می‌کند:

$account = App\Account::find(10);

$user->account()->associate($account);

$user->save();

هنگام حذف یک رابطه‌ی belongsTo نیز باید از متد dissociate بهره ببریم. این متد کلید خارجی رابطه را به null تغییر می‌دهد:

$user->account()->dissociate();

$user->save();

 ذخیره، بروزرسانی و حذف در روابط چند به چند

مباحث مربوط به ذخیره سازی اطلاعات برای روابط چند به چند متفاوت تر است. و خبری از دستورهای save یا create و متدهای associate یا dissociate نیست.

اضافه کردن یک رکورد جدید

پس از اینکه روابط مشخصی بین مدل‌های چند به چند برقرار شد باید به نحوه‌ی ذخیره کردن اطلاعات رو بروزرسانی آنها در کنترلر بپردازیم. به عنوان مثال می‌خواهیم یک نقش برای کاربر تعریف کنیم. برای اینکار کاربر موردنظر را انتخاب کرده و با استفاده از دستور attach آن نقش را به کاربر ضمیمه یا پیوست می‌کنیم:

$user = User::find($user_id);
$user->roles()->attach($role_id);

در نتیجه با اعمال دستور فوق در کنترلر یک ردیف یا رکورد به جدول role_user اضافه خواهد شد که مقدار ستون‌های user_id‌ و role_id آن معادل مقادیر متغییرهای user_id$ و role_id$ است.

حذف کردن یک رکورد

برای حذف کردن یک رکورد نیز باید از متد detach استفاده کرد. این متد نقشی که به کاربر پیوست شده است، را جدا می‌کند. برای استفاده از این متد به صورت زیر عمل می‌کنیم:

$user->roles()->detach($role_id);

همچنین برای حذف تمام نقشهای کاربران در جدول میانی role_user باید از دستور زیر استفاده کنیم:

$user->roles()->detach();

در نظر داشته باشید که متدهای attach و detach همواره مقادیر متفاوتی را به عنوان آرایه می‌پذیرند:

$user->roles()->attach([123, 456, 789]);
$user->roles()->detach([321, 654, 987]);

بروزرسانی یک رکورد

و اما مهم ترین دستور که برای بروزرسانی این جداول مورد استفاده قرار می‌گیرد، دستور بروزرسانی است که با متد sync صورت می‌پذیرد. بنابراین برای بروزرسانی دسته‌ای چند رکورد در جدول میانی باید از آرایه استفاده کرد:

$role->users()->sync([1, 2, 3]);

با اعمال دستور فوق به صورت دسته‌ای نقش‌های کاربران با id‌های ۱ و ۲ و ۳ تغییر کرده و بروزرسانی می‌شود.

در صورتیکه بخواهیم یک رکورد را بدون detach کردن آی دی های مشخص بروزرسانی کنیم باید از دستور syncWithoutDetaching استفاده کنیم:

$user->roles()->syncWithoutDetaching([1, 2, 3]);

ذخیره اطلاعات اضافه در یک جدول میانی یا Pivot Table

همانطور که در مثال ذکر کردیم می‌توان ستون‌های مختلفی به جدول میانی یا pivot table با استفاده از متد withPivot اضافه کرد. مثلا فرض کنید به جدول میانی role_user یک ستون دیگر به نام‌ registerDay اضافه کنیم. آنگاه تمام متدهای attach و detach‌ و sync برای این پارامتر اضافه نیز اعمال می‌شود:

$user->roles()->attach(1, 'registerDay' => '12 bahman');

بروزرسانی یک رکورد در جدول میانی یا Pivot Table

درصورتیکه بخواهیم یک رکورد از جدول میانی یا Pivot Table را بروزرسانی کنیم باید از متد iupdateExistingPivot استفاده کنیم. این متد کلید خارجی یک رکورد میانی را به همراه آرایه‌ای از صفات دریافت کرده و بروزرسانی می‌کند:

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

$user->roles()->updateExistingPivot($roleId, $attributes);

تاثیرگذاری روی Timestamps مدل والد

گاها برای ما پیش آمده است که می‌خواهیم هنگامیکه ستون updated_at در یک مدل فرزند بروزرسانی شد، تاثیر آن روی مدل والد نیز مشخص شود و ستون updated_at در مدل و جدول والد نیز بروزرسانی شود. برای اینکه این کار به صورت اتوماتیک صورت پذیرد باید متغییر touches$ را به صورت زیر تعریف کرد و مدل یا مدل‌های والد را درون آرایه‌ای به آن انتساب داد:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Comment extends Model
{
    /**
     * All of the relationships to be touched.
     *
     * @var array
     */
    protected $touches = ['post'];

    /**
     * Get the post that the comment belongs to.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }
}

 

بسیار عالیست! با مطالعه این بخش تمام روش‌های بروزرسانی حذف یا اضافه کردن اطلاعات که دارای روابط جداول هستند را فرا گرفتید. فصل ۱۲ با ۴ بخش کلی به اتمام رسید و هم اکنون می‌توانید به صورت کامل و بدون هیچگونه مشکل سیستم دیتابیس خود را طراحی و اجرا کنید.

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

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.