Eloquent یک نگاشت رابطه به شیء یا ORM است که به صورت پیش‌فرض در فریم‌ورک لاراول وجود دارد. در این سری از مطالب که بر پایه یک پروژه نمونه ارائه می‌شوند، قصد داریم که شما را با نحوه ساخت کوئری‌های پایگاه داده و کار با روابط در Laravel Eloquent آشنا کنیم. برای این منظور از یک اپلیکیشن نمونه استفاده می‌کنیم که آن را رفته‌رفته با مدل‌ها و روابط جدید ارتقا می‌دهیم. در مطلب قبلی در این رابطه، به تعریف یک فرمان Artisan برای حذف لیست لینک‌ها از پایگاه داده پرداختیم. امّا گاهی اوقات لازم است که لینک‌ها بین لیست‌ها در پایگاه داده جابجا شوند و گاهی نیز توضیحات یک لینک اصلاح شود. در این مطلب، به نحوه بروزرسانی رکوردهای پایگاه داده در لاراول Eloquent می‌پردازیم.

برای این منظور، یک فرمان جدید Artisan برای بروزرسانی لینک‌های کنونی در پایگاه داده ایجاد خواهیم کرد.

ایجاد یک فرمان جدید artisian به منظور بروزرسانی رکوردهای پایگاه داده

ابتدا از طریق ترمینال، مطمئن شوید که در دایرکتوری ریشه پروژه خودتان قرار دارید. سپس فرمان زیر برای پایه‌ریزی یک فرمان جدید Artisan اجرا نمایید.


docker-compose exec app php artisan make:command LinkUpdate

در نتیجه، یک فایل جدید با نام LinkUpdate.php در مسیر app/Console/Commands ساخته می‌شوشد. سپس این فایل را در ویرایشگر کرد دلخواهتان باز کنید.


app/Console/Commands/LinkUpdate.php

این فایل حاوی کد اولیه برای فرمان جدید Artisan است. این کد را برای مدیریت ویرایش یک لینک بر اساس شناسه منحصر به فردش بروزرسانی می‌کنید. متد handle() می‌بایست کارهای زیر را برایتان انجام دهد.

  • به‌دست آوردن شناسه‌ای که توسط کاربر ارائه شده و بررسی وجود لینک مطابق با این شناسه در پایگاه داده.
  • در صورتی که این لینک وجود نداشته باشد، پیغام خطا نمایش داده شده و برنامه بسته شود.
  • در صورتی که لینک وجود داشته باشد، پیغام درخواست مقادیر جدید توضیحات و لیست لینک‌ها برای کاربر ظاهر شود.
  • درخواست از کاربر برای تأیید تغییرات.
  • پس از تأیید، بروزرسانی رکورد در پایگاه داده انجام شود.

کار را با یک سری تعاریف در ابتدای فایل شروع می‌کنیم. این کار باعث تسهیل ارجاع به کلاس‌های Link و LinkList در ادامه خواهد شد.


<?php

namespace App\Console\Commands;

use App\Models\Link;

use App\Models\LinkList;

use Illuminate\Console\Command;

...

برای به‌دست آوردن شناسه لینک، باید یک آرگومان اجباری در فرمان جدید link:update تعریف کنید. کاربران در هنگام اجرای فرمان می‌توانند این پارامتر را تعریف کنند. تعریف signature فرمان را در ابتدای فایل پیدا کرده و آن را با خطوط زیر جایگزین نمایید.


...

class LinkUpdate extends Command

{

/**

* The name and signature of the console command.

*

* @var string

*/

protected $signature = 'link:update {link_id}';

...

اگر فایل را ذخیره و فرمان را اجرا کنید، بدون اینکه آرگومانی به آن اضافه نمایید، با پیغام خطا روبرو خواهید شد.


docker-compose exec app php artisan link:update

خروجی


Not enough arguments (missing: "link_id").

در متد handle() می‌بایست شناسه لینک ارائه‌شده توسط کاربر را دریافت کرده و موقعیت آن را در پایگاه داده پیدا کنید. چنین کاری با استفاده از متد argument() (از کلاس مادر Command) قابل‌انجام است. سپس می‌توانید با کمک متد find() Eloquent یک درخواست  پایگاه داده برای لینک با شناسه موردنظر بدهید. اگر نتیجه متد find() با null همراه شود، به معنای آن است که هیچ لینکی با این شناسه یافت نشده و برنامه همراه با خطا بسته می‌شود.


...

/**

* Execute the console command.

*

* @return int

*/

public function handle()

{

$link_id = $this->argument('link_id');

$link = Link::find($link_id);

if ($link === null) {

$this->error("Invalid or non-existent link ID.");

return 1;

}

// obtain updated information from user

}

...

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


...

if ($link === null) {

$this->error("Invalid or non-existent link ID.");

return 1;

}

$link->description = $this->ask('Link Description (ENTER to keep current)') ?? $link->description;

$list_name = $this->ask('Link List (ENTER to keep current)') ?? $link->link_list->title;

...

این کد باعث اخطار به کاربر برای توضیح و لیست جدید می‌شود و در عین حال، مقادیر موجود را به عنوان پیش‌فرض حفظ می‌کند. در صورتی که کاربر نخواهد این مقادیر پیش‌فرض را تغییر دهد، می‌تواند با زدن کلید Enter از این مرحله گذر کند.

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


...

$link->description = $this->ask('Link Description (ENTER to keep current)') ?? $link->description;

$list_name = $this->ask('Link List (ENTER to keep current)') ?? $link->link_list->title;

$this->info("Description: $link->description");

$this->info("Listed in: " . $list_name);

if ($this->confirm('Is this information correct?')) {

//code that updates the link

}

...

درون بلوک if، باید کار با «بررسی وجود لیست» شروع کنید. در غیر این صورت، یک لیست جدید با نام ارائه‌شده بسازید. سپس از متد associate() برای بروزرسانی رابطه بین لینک و لیست «مادر» استفاده می‌شود. نهایتاً متد save() تغییرات را به پایگاه داده انتقال می‌دهد.


...

if ($this->confirm('Is this information correct?')) {

$list = LinkList::firstWhere('slug', $list_name);

if (!$list) {

$list = new LinkList();

$list->title = $list_name;

$list->slug = $list_name;

$list->save();

}

$link->link_list()->associate($list)->save();

$this->info("Updated.");

}

...

فایل تکمیل‌شده LinkUpdate.php به صورت زیر خواهد بود.


<?php

namespace App\Console\Commands;

use App\Models\Link;

use App\Models\LinkList;

use Illuminate\Console\Command;

class LinkUpdate extends Command

{

/**

* The name and signature of the console command.

*

* @var string

*/

protected $signature = 'link:update {link_id}';

/**

* The console command description.

*

* @var string

*/

protected $description = 'Update a link in the database';

/**

* Create a new command instance.

*

* @return void

*/

public function __construct()

{

parent::__construct();

}

/**

* Execute the console command.

*

* @return int

*/

public function handle()

{

$link_id = $this->argument('link_id');

$link = Link::find($link_id);

if ($link === null) {

$this->error("Invalid or non-existent link ID.");

return 1;

}

$link->description = $this->ask('Link Description (ENTER to keep current)') ?? $link->description;

$list_name = $this->ask('Link List (ENTER to keep current)') ?? $link->link_list->title;

$this->info("Description: $link->description");

$this->info("Listed in: " . $list_name);

if ($this->confirm('Is this information correct?')) {

$list = LinkList::firstWhere('slug', $list_name);

if (!$list) {

$list = new LinkList();

$list->title = $list_name;

$list->slug = $list_name;

$list->save();

}

$link->link_list()->associate($list)->save();

$this->info("Updated.");

}

return 0;

}

}

پس از اتمام کار، فایل را ذخیره کنید. اکنون با استفاده از فرمان link:show کل لینک‌ها و شناسه مطابق با آنها را دریافت نمایید.


docker-compose exec app php artisan link:show

نمونه خروجی


+----+-------------------------------------------------+--------------+----------------------------------+

| id | url                                             | list         | description                      |

+----+-------------------------------------------------+--------------+----------------------------------+

| 1  | https://ariaservice.net/community              | default      | DO Community                     |

| 2  | https://ariaservice.net/community/tags/laravel | default      | Laravel Tutorias at AriaService |

| 3  | https://ariaservice.net/community/tags/php     | default      | PHP Tutorials at AriaService    |

| 4  | https://twitter.com/ariaservice                | social       | Twitter                          |

| 5  | https://dev.to/ariaservice                     | social       | DEV.to                           |

| 6  | https://laravel.com/docs/8.x/eloquent           | default      | Laravel Eloquent Docs            |

+----+-------------------------------------------------+--------------+----------------------------------+

سپس یک آیتم برای ویرایش انتخاب کنید. به عنوان مثال، ممکن است بخواهید یک لیست از لینک‌هایی به وب‌سایت آریانت ارجاع داده می‌شوند، تهیه کنید. بنابراین، شناسه‌های 1، 2 و 3 مدّنظر شما خواهند بود.

برای بروزرسانی لینک با شناسه 1 داریم:


docker-compose exec app php artisan link:update 1

خروجی


Link Description (ENTER to keep current):

> DO Community

Link List (ENTER to keep current):

> ariaservice

Description: DO Community

Listed in: ariaservice

Is this information correct? (yes/no) [no]:

> y

Updated.

سپس با فرمان link:show از بروزرسانی رکوردهای پایگاه داده مطمئن شوید.

خروجی


+----+-------------------------------------------------+--------------+----------------------------------+

| id | url                                             | list         | description                      |

+----+-------------------------------------------------+--------------+----------------------------------+

| 1  | https://ariaservice.net/community              | ariaservice | DO Community                     |

| 2  | https://ariaservice.net/community/tags/laravel | ariaservice | Laravel Tutorias at AriaService |

| 3  | https://ariaservice.net/community/tags/php     | ariaservice | PHP Tutorials at AriaService    |

| 4  | https://twitter.com/ariaservice                | social       | Twitter                          |

| 5  | https://dev.to/ariaservice                    | social       | DEV.to                           |

| 6  | https://laravel.com/docs/8.x/eloquent           | default      | Laravel Eloquent Docs            |

+----+-------------------------------------------------+--------------+----------------------------------+

جمع‌بندی

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