2020.2.11
研修
システム開発する上で、DB のリレーションは便利です。
今回は、私が Laravel でシステム開発したときのことをまとめています。
リレーションを組むことこそ、DBの真骨頂ですからね。
最大限にパワーを発揮できるように、理解したいと思います。
「Items」テーブルに「Users」の主キー「id」を紐づけしたいと考えました。
以下の図のようなイメージですね。
Users テーブルはデフォルトで作られているため、特に変更せず
今回は Items テーブルのマイグレーションから作成していきます。
create_items_table の作成 |
1.プロジェクトフォルダで、ターミナルを開きます。
$ cd test // 現在の階層の中のtest(フォルダ)に移動する
2.ターミナルで以下のコマンドを叩きます。
$ php artisan make:migration create_items_table
※create_(作成したいテーブル名)_table で作成します。
また、テーブル名は 複数形 、モデル名は 単数形 を使います。
これにより、database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.php
が生成されます。
※YYYY_mm_dd_XXXXXX
には作成した日時が入ります。
カラムの編集および外部キーの設定 |
database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.php
のup()
を編集します。
database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.php
public function up()
{
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->text('text')->nullable();
$table->bigInteger('user_id');
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users');
});
}
これで外部キーとして渡すことができます。
抜粋
$table->foreign('user_id')->references('id')->on('users');
// $table->foreign(外部キーカラム)->references(主キーカラム)->on(主キーテーブル);
しかし、
これだけでは上手くいかないんです。
->unsigned() の追加 |
実は->bigIncrements()
で指定されている主キーは自動でUNSIGNED
が追加されています。
そのため、外部キーでも指定が必要です。
database/migrations/YYYY_mm_dd_XXXXXX_create_items_table.php
$table->bigInteger('user_id')->unsigned();
これで、外部キーが正常に渡せる状態になりました。
これで DB のリレーション自体は完了しているのですが、
もう少し呼び出しやすくするために、各テーブルのモデル同士でもリレーションを組んでいきます。
モデルの作成 |
すでにデフォルトで「User モデル」が存在するため、今回は「Item モデル」を作成します。
$ php artisan make:model Item
これで、app/Item.php
が生成されます。
リレーションの設定 |
さて、リレーションを設定する訳なのですが、
ここで改めて「Users」と「Items」の関係をイメージしてみます。
このようなイメージですね。
各 User がいくつかの Item を持っている状態をイメージしています。
ここで大事なのは、
という情報です。
今回でいうと、
「一人のUserが複数のItemを持っている → 1:多」です。
それぞれリレーションの設定方法が違うので、注意してください。
今回他は割愛し、1:多のみを説明します。
他の情報が欲しい方はLaravel 公式を参照してください。
まずは、主体となる「Users」の方から追記します。
以下のコードを追加してください。
app/User.php
class User extends Authenticatable
{
----------(略)----------
+ public function items()
+ {
+ return $this->hasMany('App\Item');
+ }
}
次に、「Items」の方です。
呼び出すメソッドが違うため注意してください。
app/Item.php
class Task extends Model
{
+ public function user()
+ {
+ return $this->belongsTo('App\User');
+ }
}
これでリレーションが設定できました。
最後にこのリレーションを使って呼び出す方法も記載しておきます。
「山田太郎」の「item」を取得 |
use App\User;
$user = User::where("name", "山田太郎");
$items = $user->items()->get();
これで山田太郎が持つ「item」を全て取得することができます。
use App\User;
$items = User::where("name", "山田太郎")->items()->get();
これも可能です。
リレーションを設定していない場合 |
リレーションを設定していない場合
use App\User;
use App\Item;
$user = User::where("name", "山田太郎")->first();
$items = Item::where("user_id", $user->id)->get();
両方呼び出す必要が出てきます。
$user->items()->get()
の方が
このユーザのアイテムをゲットと分かりやすいですね。
今回は比較的簡単なDB設計だと思います。
もっと大掛かりなシステムとなれば、リレーションも複雑になったり
多:多なども出てくることと思います。
そのため、ER図(Entity Relationship)を描いたりして、
しっかりと頭の中でもイメージを明確に持つことは重要だと感じました。
最後まで読んでいただき、ありがとうございました。