laravelのpivotいいなと思ったの巻
yii ActiveRecord の弱点
yii ActiveRecord は、many-manyの中間テーブルに属性を付けにくい弱点があります。たとえばこんな問題とか。
Accessing data in a join table with the related models
いまだにキレイな解決方法がない。と思う。ほんとにないの?
laravel は pivot で解決
一方、laravelならこう書く。
テーブル
CREATE TABLE viewer ( id INT NOT NULL PRIMARY KEY, name VARCHAR(45)); CREATE TABLE movie ( id INT NOT NULL PRIMARY KEY, title VARCHAR(45)); CREATE TABLE viewer_watched_movie ( id INT NOT NULL, -- <--- ここ見逃さない viewer_id INT NOT NULL, movie_id INT NOT NULL, liked TINYINT(1), PRIMARY KEY (id), CONSTRAINT fk_viewer_watched FOREIGN KEY (movie_id) REFERENCES movie (id), CONSTRAINT fk_movie_watched_by FOREIGN KEY (viewer_id) REFERENCES viewer (id));
viewerモデル
<?php class Viewer extends Eloquent { public static $table = 'viewer'; public function movies() { return $this->has_many_and_belongs_to('Movie', 'viewer_movies') ->with('liked'); // <--- この with が大事 } }
movieモデル
<?php class Movie extends Eloquent { public static $table = 'movie'; }
コントローラー
<?php $viewer = Viewer::find(1); foreach ($viewer->movies()->get() as $movie) echo $viewer->name . ($movie->pivot->liked ? ' liked ' : ' didn’t like ') // <--- pivot で with したカラムを参照できる . $movie->title ."<br>" ;
うん、素直に書けた。しかも冒頭挙げたページのproblemコードと酷似したコードで書けてる。
注意
pivot テーブルに created_at, updated_at がないと、こんなエラーがでる。
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'viewer_movies.created_at' in 'field list'
そんなときは、 application/start.php にこれを書いておく。
Laravel\Database\Eloquent\Pivot::$timestamps = false;
pivot テーブルに created_at, updated_at を要求するのはお節介なような気が。
参考
Eloquent ORM - laravel 日本語ドキュメント
Disable timestamps in pivot table ? - github/laravel/issues/543
laravelを使おうかと思った理由の一つがコレ