LaravelのORM機能 Eloquent の EagerLoading
LaravelのORM Eloquentには、Eager Loadingという機能がある。
モデル内に定義されたメソッドを元に自身以外の他テーブルからデータを引っ張りだしてくれる便利な機能。
例えば、以下の様なECサイトのテーブル構成でイメージしてみる。
商品テーブルにはimage_idというサムネイル用のIDが定義されており、画像テーブルのimage_idにリンクされている。
やりたいこととしては、商品情報と画像の情報を一度に取得するというもの。
モデルの定義は割と簡単で以下のように設定する。
<?php // models/item.php class Item extends Eloquent{ public static $table = "item"; public static $key = "item_id"; public static $timestamps = false; // サムネイル function thumb(){ return $this->belongs_to("Image","image_id"); } } // models/image.php class Image extends Eloquent{ public static $table = "image"; public static $key = "image_id"; public static $timestamps = false; }
で、問題はコントローラー側でどういう呼び出し方をするのか?
Eloquentでは、必ず、staticなwithメソッドからスタートさせなければならないルールがある。
<?php /* コントローラー側の処理 */ // すべての商品をサムネイルと一緒に取得 $itemList=Item::with("thumb")->get(); // 条件を付与 $itemList=Item::with("thumb") ->where("price",">",500) ->where("del_flg","=",0) ->get(); // 情報の呼び出し方 foreach($itemList as $value){ echo $value->item_name." ".$value->price."円 :"; echo $value->thumb->file_name; } // 出力 // 銅の剣 500円:thumb_ken.jpg ?>
といった具合な事を書く。ちなみに、以下が実行されるSQL。
SELECT * FROM `item`; SELECT * FROM `image` WHERE `item_image_id` IN (1,2,3); SELECT * FROM `item` WHERE `price` > 500 AND `del_flg`=0; SELECT * FROM `image` WHERE `item_image_id` IN (1,3);
見ての通り、JOINなどでテーブル結合しているわけではなく、一度、商品テーブルからデータを取得した後、
image_idをIN句でくくって、取得するという方法が取られている。
これに関しては、まぁ、色々と議論の余地はあるんでしょうが、チャチャっと作りたい人には便利な機能かもしれません。