FuelPHPを使ったリレーションがやっとわかったのでメモしておきます。
要件は下記の通り。
テーブル「カード」と、
テーブル「ユーザーが所持するカード一覧」の2種類を用意し、
特定のユーザーが持っているカードだけ抽出する
まずは「カード」のテーブルを作成します。
カードID、カード名だけの単純なテーブルです。
CREATE TABLE `testdb`.`table_card` ( `cardid` VARCHAR( 32 ) NOT NULL UNIQUE, `name` VARCHAR( 256 ), INDEX ( `cardid` ) ) ENGINE = MYISAM ;
次にユーザーが所有するカードの一覧のテーブルです。
こちらもシリアル、ユーザーID、カードID、枚数だけの単純なもの。
CREATE TABLE `testdb`.`table_userscard` ( `id` SERIAL NOT NULL DEFAULT NULL UNIQUE, `userid` VARCHAR( 256 ), `cardid` VARCHAR( 32 ), `count` INT, INDEX ( `id` ) ) ENGINE = MYISAM ;
単純な \Fuel\Core\Model_Crud ではなく、\Orm\Model を使います。
ORM(オブジェクトリレーショナルマッパー)はざっくり言うと“リレーションを組むのに便利なモデル”です。
ORMを使うには事前に準備が必要になります。
≫Introduction - Relations - Orm Package - FuelPHP Documentation
≫FuelPHPのORM(オブジェクトリレーショナルマッパー) | WinRoad徒然草
≫FuelPHPをやってみる (8) - Orm\Modelを試す - - kinjou_jのメモログ
いよいよORMを継承したクラスを作ります。
まずはユーザーの所有カード。
バリデーションの設定など色々行えますが、ここではシンプルに。
fuel/app/classes/model/userscard.php
class Model_Userscard extends \Orm\Model{ protected static $_table_name = 'table_userscard'; protected static $_primary_key = array('id'); protected static $_propeties = array( 'id', 'userid', 'cardid', 'count' ); }
そしてリレーションを設定するカードのモデル。
fuel/app/classes/model/card.php
class Model_Card extends \Orm\Model{ protected static $_table_name = 'table_card'; protected static $_primary_key = array('cardid'); protected static $_propeties = array( 'cardid', 'name' ); /********************************** * リレーション:一対多 */ protected static $_has_many = array( 'owncard' => array( 'model_to' => 'Model_Userscard', 'key_from' => 'cardid', 'key_to' => 'cardid', 'cascade_save' => false, 'cascade_delete' => false ) ); }
key_from、key_toで結合する項目を指定しています。
また、cascade_save、cascade_deleteは「false」にして、カード情報を変更や削除しても、所有情報には影響が出ないようにしています。
そしていよいよ本番! リレーションを使い、かつ、リレーション内での絞り込みです。
$results = Model_Card::find( 'all', array( 'related' => array( 'owncard' => array( // リレーション条件を指定 'where'=> array( // リレーション内での検索 array( 'userid', '=', 'ABC12345' ) ) ) ), // table_card 側での検索はこっちに記述 // 'where' => array( // array( 'exp' => 3 ) // ), 'order_by' => array( 'cardid'=> 'asc' ) ));
モデル内で作成したリレーション条件名を「related」で指定し、
その中で同じように「where」を指定するだけなのですが、
これがなぜか情報が見付かりませんでした。^^;
同じ状況で悩んでいる方のお役に立てればと。
\Orm\Model を継承した場合と、\Fuel\Core\Model_Crud を継承した場合ではメソッド名も違いますし、取得できるデータ形式もだいぶ違いますので注意が必要です。
一度 var_dump() で確認してみてください。
No comments yet.