前回から、モデルを定義して、モデルと密接に関係しているデータベースとの関わり合いをうまいところやってくれるらしいEloquent ORMというものをいろいろ探って試行錯誤してみていたけど、よくわかっていない。とりあえずやったことを書き残す。
前回、troubleというモデルをartisanコマンドでひな形を作ったところで終わった。で、私の設計上、このtroubleというモデルは、自らに対して1対nの関連性を持つような想定だ。親のtroubleに、複数のtroubleがぶらさがる、ツリー構造のようなイメージだ。
で、troubleがもつカラムとしては、長文のテキスト「document」の1つのみとした。
まずは前回atrisanコマンドで作ってもらったマイグレーション用のファイルdatabase/migrations/~create_troubles.php をいろいろなドキュメントを見よう見まねで修正した。因みにupメソッドが作成するとき、downメソッドが元に戻すときのことを書くらしい。
1 2 3 4 5 6 7 8 9 10 11 12 |
public function up() { Schema::create('t_troubles', function (Blueprint $table) { $table->increments('id'); $table->longText('document'); $table->integer('trouble_id')->unsigned()->nullable(); $table->timestamps(); $table->foreign('trouble_id')->references('id')->on('t_troubles') ->onDelete('cascade'); }); } |
この5行目でdocumentカラムの定義だが、6行目では、自分の親のidを納めるtrouble_idカラムを定義している。そして、9行目で、外部キー束縛を定義している。これでマイグレーションをし直す。
> php artisan migrate:refresh
すると、MySQLのデータベースを見ると、テーブルに「document」と「trouble_id」のカラムが追加されている。よしよし。
そして、今度は、App\Trouble.phpを以下のように修正した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Trouble extends Model { protected $table = 't_troubles'; public function troubles() { return $this->hasMany('App\Trouble','trouble_id','id'); } public function owner() { return $this->belongsTo('App\Trouble'); } } |
ここでテーブル間の相関関係を定義するらしい。便宜上ツリーに見立てて1を親、nを子として説明するが、hasManyが、子クラス(App\Trouble)と親のApp\Trouble間には、子のtrouble_idに親のidをもつ形で複数の関係あるよ、ということになって、belongsToは、その逆、子から1つの親があるよ、ということになるらしい。
さらに、Seederっていって、データベースの初期状態を定義できる仕組みを使って、操作方法を確かめてみる。databases\seeda\DatabaseSeeder.phpを以下のように修正した。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
use Illuminate\Database\Seeder; use Illuminate\Database\Eloquent\Model; use app\Trouble; class DatabaseSeeder extends Seeder { /** * Run the database seeds. * * @return void */ public function run() { // $this->call(UsersTableSeeder::class); Model::unguard(); $this->call('TroubleTableSeeder'); Model::reguard(); } } class TroubleTableSeeder extends Seeder { public function run() { DB::table('t_troubles')->delete(); $trb1 = new App\Trouble(['document'=>'こんにちは世界']); $trb2 = new App\Trouble(['document'=>'ぶらさがります']); $trb3 = new App\Trouble(['document'=>'こっちもぶらさがり']); $trb1->save(); $trb1->troubles()->save($trb2); $trb1->troubles()->save($trb3); } } |
で、artisanにてseedを実行!
> php artisan db:seed
そしてt_troubleテーブルを見ると、「ぶらさがります」と「こっちもぶらさがり」のtrouble_idに、「こんにちは世界」のidが入っているのがわかる。うまくいっているようですねー。
親を先にsaveでDBに格納しておかないと、親のIDがわからないので、当然うまくいかないようだ。そしてtrb1のtroublesで関連づけたくてtrb2を書き込むときは、「$trb1->troubles()->save($trb2)」って書くところがなかなか思いつかないのねー。
この状態で、
1 |
$data = Trouble::find('1')->troubls; |
とやると、idが1のレコードにぶら下がるレコード群をdata変数へ得ることができるようです。
今日はここまで…