LaravelEloquentでデータベースレコードを更新する方法

提供:Dev Guides
移動先:案内検索

このシリーズの前のセクションでは、新しいリスト機能をサポートするために、既存のArtisanコマンドを更新しました。 リンクを挿入および削除するコマンドはありますが、デモアプリケーションには現在、既存のリンクを編集するコマンドがありません。 これは、たとえば、リスト間でリンクを移動したり、リンクの説明を更新したりする場合に役立ちます。

このガイドでは、データベース内の既存のリンクを更新するための新しいArtisanコマンドを作成します。

ターミナルから、最初にプロジェクトのルートディレクトリにいることを確認してから、次のコマンドを実行して新しいArtisanコマンドをブートストラップします。

docker-compose exec app php artisan make:command LinkUpdate

これにより、app/Console/Commandsに新しいLinkUpdate.phpファイルが作成されます。 選択したコードエディタでファイルを開きます。

app/Console/Commands/LinkUpdate.php

このファイルには、新しいArtisanコマンドのボイラープレートコードが含まれています。 一意のidを指定して、リンクの編集を処理するように更新します。 これは、handle()メソッドが実行する必要があることです。

  • ユーザーから提供されたidを取得し、データベース内にidと一致するリンクが存在するかどうかを確認します。
  • 有効なリンクが見つからない場合は、エラーメッセージを表示して終了します。
  • 有効なリンクが見つかった場合は、リンクの説明とリンクリストの更新された値を提供するようにユーザーに促します。
  • ユーザーに変更を確認するように依頼します。
  • 確認したら、データベース内のアイテムを更新します。

後でLinkおよびLinkListクラスを参照しやすくするために、ファイルの先頭にいくつかのuse定義を含めることから始めます。

app / Console / Commands / LinkUpdate.php

<?php
 
namespace App\Console\Commands;
 
use App\Models\Link;
use App\Models\LinkList;
use Illuminate\Console\Command;
 
...

リンクidを取得するには、新しいlink:updateコマンドで必須の引数を設定する必要があります。これにより、ユーザーは実行時にそのパラメーターを指定する必要があります。 ファイルの上部にあるコマンド署名定義を見つけて、強調表示された行に置き換えます。

app / Console / Commands / LinkUpdate.php

...
 
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
OutputNot enough arguments (missing: "link_id").

handle()メソッドでは、ユーザーから提供されたリンク id を取得し、データベースで見つける必要があります。 これは、親Commandクラスを介して提供されるargument()メソッドを使用して実行できます。 次に、find() Eloquentメソッドを使用して、そのidのリンクをデータベースに照会できます。 find()メソッドがnullを返す場合、その id とのリンクが見つからなかったことを意味するため、プログラムはエラーで終了するはずです。

app / Console / Commands / LinkUpdate.php

...
   /**
     * 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メソッドを使用してこれを行うことができます。

app / Console / Commands / LinkUpdate.php:関数handle()

...
        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()メソッドを使用して、ユーザーに変更を確認してもらうことをお勧めします。 このようなコードは次のようになります。

app / Console / Commands / LinkUpdate.php:関数handle()

...
        $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()メソッドは、最後に、データベースへの変更を保持します。

app / Console / Commands / LinkUpdate.php:関数handle()

...
        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ファイルです。

app / Console / Commands / 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;
    }
}

注: Artisanコマンドの詳細については、Laravelの紹介シリーズの一部であるLaravelでデータベースレコードを管理するArtisanコマンドを作成する方法のガイドを確認してください。


終了したらファイルを保存します。 次に、link:showコマンドを使用して、すべてのリンクとそれぞれのIDを取得します。

docker-compose exec app php artisan link:show 
Output+----+-------------------------------------------------+--------------+----------------------------------+
| id | url                                             | list         | description                      |
+----+-------------------------------------------------+--------------+----------------------------------+
| 1  | https://digitalocean.com/community              | default      | DO Community                     |
| 2  | https://digitalocean.com/community/tags/laravel | default      | Laravel Tutorias at DigitalOcean |
| 3  | https://digitalocean.com/community/tags/php     | default      | PHP Tutorials at DigitalOcean    |
| 4  | https://twitter.com/digitalocean                | social       | Twitter                          |
| 5  | https://dev.to/digitalocean                     | social       | DEV.to                           |
| 6  | https://laravel.com/docs/8.x/eloquent           | default      | Laravel Eloquent Docs            |
+----+-------------------------------------------------+--------------+----------------------------------+

次に、編集するアイテムを選択します。 たとえば、DigitalOcean Webサイトを指すリンク(ID 12 、および3(前の出力例)。

ID 1 でリンクを更新するには、次のコマンドを実行します。

docker-compose exec app php artisan link:update 1 
Output Link Description (ENTER to keep current):
 > DO Community

 Link List (ENTER to keep current):
 > digitalocean

Description: DO Community
Listed in: digitalocean

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

Updated.

次に、link:showコマンドを再度実行して、更新された情報を確認します。

Output+----+-------------------------------------------------+--------------+----------------------------------+
| id | url                                             | list         | description                      |
+----+-------------------------------------------------+--------------+----------------------------------+
| 1  | https://digitalocean.com/community              | digitalocean | DO Community                     |
| 2  | https://digitalocean.com/community/tags/laravel | digitalocean | Laravel Tutorias at DigitalOcean |
| 3  | https://digitalocean.com/community/tags/php     | digitalocean | PHP Tutorials at DigitalOcean    |
| 4  | https://twitter.com/digitalocean                | social       | Twitter                          |
| 5  | https://dev.to/digitalocean                     | social       | DEV.to                           |
| 6  | https://laravel.com/docs/8.x/eloquent           | default      | Laravel Eloquent Docs            |
+----+-------------------------------------------------+--------------+----------------------------------+

このガイドでは、LaravelEloquentでデータベースレコードを更新する方法を学びました。 デモアプリケーションをアップグレードして、ユーザーがデータベース内の既存のリンクを編集できるようにする新しいコマンドを追加しました。

このシリーズの次の最後のパートでは、リンクのリストを削除するための新しいコマンドを作成します。