Laravel 外部キーやリレーションなど

productsテーブル作成

productモデル、マイグレーション作成

外部キーを設定する際には、親のモデルを削除するかどうか、親を削除したときに同時に削除するかを考える必要がある。

ownerを削除したらshopも消える、shopが消えたらproductも消えるようにする→cascadeで削除
今回はcategoryは消えないようにするので、cascadeなし。

モデル名_idとすることでLaravelが自動でどのモデルか推測してくれるがimage1はできないので、constrained('images')でどのモデルか指定する

<?php
public function up()
{
    Schema::create('products', function (Blueprint $table) {
        $table->id();
        //ownerを削除したらshopも消える、shopが消えたらproductも消えるようにする→cascade
        $table->foreignId('shop_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
        $table->foreignId('secondary_category_id')->constrained();
        //モデル名_idとすることでLaravelが自動でどのモデルか推測してくれるがimage1はできないので、constrained('images')どのモデルか指定する
        //画像はからの場合もあるのでnullableをつける
        $table->foreignId('image1')->nullable()->constrained('images');
        $table->timestamps();
            
    });
}
Route

ルーティング(リソース)

<?php
//productのルート(resource)
Route::resource('products', ProductController::class)
//adminで認証していたらで表示
->middleware('auth:owners')->except('show');

ProductController作成(リソース)

モデルの中でリレーションを定義

productモデルにリレーションを追記していく。
categoryやimageを複数の中から1つを選ぶのでbelongs toとする

  • リレーション関係のメソッドの書き方
    第1引数・・紐付けるモデル
    第2引数・・カスタム外部キー名
    第3引数・・親モデルが主キーとしてidを使用していない場合、カスタムキーを指定する

モデル名_idとすることでLaravelが自動でどのモデルか推測してくれるがimage1のように
_idをつけないと推測されないので、idと紐付けると追加

<?php

namespace Database\Seeders;
use Illuminate\Support\Facades\DB;

use Illuminate\Database\Seeder;

class ProductSeeder extends Seeder
class Product extends Model
{
    use HasFactory;

    public function shop()
    {   //productはshopに属する。
        return $this->belongsTo(Shop::class);
    }
    public function imageFirst()
    {   //productはImageに属する。
        return $this->belongsTo(Image::class,'image1','id');
    }
    public function category()
    {   //productはsecondaryCategoryに属する。メソッド名を変えたので外部キーもかく
        return $this->belongsTo(SecondaryCategory::class,'secondary_category_id');
    }
}
Tinkerでリレーションの確認

Stocksテーブル作成

在庫管理・履歴用のテーブルとして作成。
在庫管理は処理が頻繁に発生するので、実際の開発環境では
マスターテーブル(参照用), トランザクションテーブル(処理用) に分けて管理する。

$ php artisan make:model Stock -m

1つのproductが複数のStockをもつ→hasMany

<?php
public function stock()
    {   //1つのproductが複数のStockをもつ。
        return $this->hasMany(Stock::class);
    }

トランザクションテーブルとしてt_テーブル名という名前で作るので、テーブル名をかえる場合はモデルに記載
する
Stock.phpprotected $table = ’t_stocks’;

マイグレーション

テーブル名をt_stocksへ変更
Upメソッド、downメソッドともにテーブル名変更

<?php
  public function up()
    {
        Schema::create('t_stocks', function (Blueprint $table) {
            $table->id();
            $table->foreignId('product_id')->constrained()->onUpdate('cascade')->onDelete('cascade');
            $table->tinyInteger('type');
            $table->integer('quantity');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('t_stocks');
    }
Seeder
root@aba451969df6:/var/www/html# php artisan make:seed StockSeeder
Seeder created successfully.

root@aba451969df6:/var/www/html# php artisan migrate:refresh --seed
<?php
public function run()
    {
        DB::table('t_stocks')->insert([
            [
                'product_id' => 1,
                'type' => 1,
                'quantity' => 5,
            ],
            [
                'product_id' => 1,
                'type' => 1,
                'quantity' => -2,
            ]]);
    }
Tinkerでリレーションの確認