PHP

Laravel リレーション 中間テーブルのカラム取得 withPivot()

Laravel

 

マイグレーションファイル作成

 

Masterモデル, mastersテーブル雛形作成

docker-compose exec php-fpm php artisan make:model Models/Master
php artisan make:migration create_masters_table

 

Pokemonモデル, pokemonsテーブル雛形作成

docker-compose exec php-fpm php artisan make:model Models/Pokemon
php artisan make:migration create_pokemons_table

 

中間テーブル master_pokemonテーブル雛形作成

docker-compose exec php-fpm php artisan make:migration create_master_pokemon_table

 

シーダファイルのテンプレート作成

docker-compose exec php-fpm php artisan make:seeder MastersTableSeeder
docker-compose exec php-fpm php artisan make:seeder PokemonsTableSeeder
docker-compose exec php-fpm php artisan make:seeder Master_PokemonTableSeeder

 

モデル定義

 

mastersテーブルのマイグレーションファイル

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Master extends Model
{
    protected $table = 'masters';
    protected $primaryKey = 'master_id';

    public function master_pokemon()
    {
        return $this->belongsToMany('App\Models\Pokemon', 'master_pokemon', 'master_id', 'pokemon_id')
            ->withPivot('comment');
    }
}

withPivot(‘カラム名’)で中間テーブルのカラムを取得しています。

 

 

pokemonsテーブルのマイグレーションファイルの修正

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use phpDocumentor\Reflection\Types\Object_;

class Pokemon extends Model
{
    protected $table = 'pokemons';
    protected $primaryKey = 'pokemon_id';

    public function master_pokemon()
    {
        return $this->belongsToMany('App\Models\Master', 'master_pokemon', 'pokemon_id', 'master_id')
            ->withPivot('comment');
    }

    public static function getPokemonName(int $id) :Object
    {
        return Pokemon::select('name')->find($id);
    }
}
  • テーブル名と主キーを指定。
  • 定義したgetPokemonName()の返り値もきちんと型宣言しましょう。

 

 

master_pokemon(中間)テーブルのマイグレーションファイルの修正

    public function up()
    {
        Schema::create('master_pokemon', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('master_id')->unsigned();
            $table->bigInteger('pokemon_id')->unsigned();
            $table->timestamps();
        });
    }

 

 

 

 

シーダファイル作成

 

MastersTableSeeder.php

<?php

use Illuminate\Database\Seeder;

class MastersTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $master = new \App\Models\Master([
            'name' => 'さとし'
        ]);
        $master->save();
 
        $master = new \App\Models\Master([
            'name' => 'たけし'
        ]);
        $master->save();
 
        $master = new \App\Models\Master([
            'name' => 'かすみ'
        ]);
        $master->save();
 
        $master = new \App\Models\Master([
            'name' => 'こじろう'
        ]);
        $master->save();
    }
}

 

 

PokemonTableSeeder.php

 

<?php

use Illuminate\Database\Seeder;

class PokemonsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        $pokemon = new \App\Models\Pokemon([
            'name' => 'ピカチュウ'
        ]);
        $pokemon->save();
 
        $pokemon = new \App\Models\Pokemon([
            'name' => 'イワーク'
        ]);
        $pokemon->save();
 
        $pokemon = new \App\Models\Pokemon([
            'name' => 'スターミー'
        ]);
        $pokemon->save();
 
        $pokemon = new \App\Models\Pokemon([
            'name' => 'ニャース'
        ]);
        $pokemon->save();
    }
}

 

中間テーブルmaster_pokemonのシーディング

<?php

use Illuminate\Database\Seeder;

class Master_PokemonTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('master_pokemon')->insert([
            'master_id' => 1,
            'pokemon_id' => 1,
            'comment' => "キミに決めた!",
        ]);
        DB::table('master_pokemon')->insert([
            'master_id' => 2,
            'pokemon_id' => 2,
            'comment' => "イワーク、ご苦労だった。"
        ]);
        DB::table('master_pokemon')->insert([
            'master_id' => 3,
            'pokemon_id' => 3,
            'comment' => "いけー!マイ ステディ!"
        ]);
        DB::table('master_pokemon')->insert([
            'master_id' => 4,
            'pokemon_id' => 4,
            'comment' => "ニャースでニャース! (せりふ) うるさい!"
        ]);
        DB::table('master_pokemon')->insert([
            'master_id' => 4,
            'pokemon_id' => 1,
            'comment' => "ピカチュウ!捕まえた〜!",
        ]);
    }
}

 

 

DatabaseSeeder.phpでシーダファイルの登録

    public function run()
    {
        // $this->call(UsersTableSeeder::class);
        $this->call(MastersTableSeeder::class);
        $this->call(PokemonsTableSeeder::class);
        $this->call(Master_PokemonTableSeeder::class);
    }

 

 

dump-autoload

$ docker-compose exec php-fpm composer dump-autoload

 

マイグレーション、シーディング

$ docker-compose exec php-fpm php artisan migrate:refresh --seed

 

 

 

Tinkerでデバッグ

 

docker-compose環境の場合

$ docker-compose exec php-fpm php artisan tinker

or

通常の場合

$ php-fpm php artisan tinker

 

 

 

>>> App\Models\Master::find(1);

=> App\Models\Master {#2966
     master_id: 1,
     name: "さとし",
     created_at: "2019-09-24 14:32:06",
     updated_at: "2019-09-24 14:32:06",
   }

 

>>> App\Models\Master::all();


=> Illuminate\Database\Eloquent\Collection {#2975
     all: [
       App\Models\master {#2970
         id: 1,
         name: "さとし",
         created_at: "2019-09-24 13:47:46",
         updated_at: "2019-09-24 13:47:46",
       },
       App\Models\master {#2965
         id: 2,
         name: "たけし",
         created_at: "2019-09-24 13:47:46",
         updated_at: "2019-09-24 13:47:46",
       },
       App\Models\master {#2981
         id: 3,
         name: "かすみ",
         created_at: "2019-09-24 13:47:46",
         updated_at: "2019-09-24 13:47:46",
       },
       App\Models\master {#2982
         id: 4,
         name: "こじろう",
         created_at: "2019-09-24 13:47:46",
         updated_at: "2019-09-24 13:47:46",
       },
     ],
   }

 

>>> App\Models\Pokemon::all();


=> Illuminate\Database\Eloquent\Collection {#2955
     all: [
       App\Models\Pokemon {#2977
         pokemon_id: 1,
         name: "ピカチュウ",
         created_at: "2019-09-24 14:32:06",
         updated_at: "2019-09-24 14:32:06",
       },
       App\Models\Pokemon {#2963
         pokemon_id: 2,
         name: "イワーク",
         created_at: "2019-09-24 14:32:06",
         updated_at: "2019-09-24 14:32:06",
       },
       App\Models\Pokemon {#2980
         pokemon_id: 3,
         name: "スターミー",
         created_at: "2019-09-24 14:32:06",
         updated_at: "2019-09-24 14:32:06",
       },
       App\Models\Pokemon {#2981
         pokemon_id: 4,
         name: "ニャース",
         created_at: "2019-09-24 14:32:06",
         updated_at: "2019-09-24 14:32:06",
       },
     ],
   }

 

中間テーブルを利用する

>>> App\Models\Pokemon::find(1)->master_pokemon()->get();


=> Illuminate\Database\Eloquent\Collection {#2964
     all: [
       App\Models\Master {#2972
         master_id: 1,
         name: "さとし",
         created_at: "2019-09-24 15:56:11",
         updated_at: "2019-09-24 15:56:11",
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#2963
           pokemon_id: 1,
           master_id: 1,
           comment: "キミに決めた!",
         },
       },
       App\Models\Master {#2975
         master_id: 4,
         name: "こじろう",
         created_at: "2019-09-24 15:56:11",
         updated_at: "2019-09-24 15:56:11",
         pivot: Illuminate\Database\Eloquent\Relations\Pivot {#2968
           pokemon_id: 1,
           master_id: 4,
           comment: "ピカチュウ!捕まえた〜!",
         },
       },
     ],
   }

 

 

pokemonモデルで定義した関数の利用

>>> App\Models\Pokemon::getPokemonName(1);


=> App\Models\Pokemon {#2971
     name: "ピカチュウ",
   }

 

関連

Laravel 中間テーブルを利用した多対多のリレーション

 

 

Amazonおすすめ

iPad 9世代 2021年最新作

iPad 9世代出たから買い替え。安いぞ!🐱 初めてならiPad。Kindleを外で見るならiPad mini。ほとんどの人には通常のiPadをおすすめします><

Laravel リレーション 中間テーブルのカラム取得 withPivot()”への2件のコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)