プログラミング言語や環境設定を中心としたパソコン関連の技術メモです。
主にシステム開発中に調べたことをメモしています。TIPS的な位置付けで、気が向いたときにちまちま更新していきます。
FuelPHP1.6、ORMモデル間の関連付け(has_one、has_many、belongs_to)を理解する。
「$_has_one」とか「$_has_many」とか「$_belongs_to」とか「$_many_many」とか
「よく分からんけど何かめんどくさそー」と敬遠していたのですが、
順を追って見ていったら簡単でした。

要するに「モデル同士をくっつける」ことができるだけなのですね。
もちっとカッコつけて言えば「テーブル(モデル)間の関連性を定義できる」でしょうか。

例えば2つのテーブル「tbl_test01」と「tbl_test02」があったとします。

■tbl_test01
 pk_id【プリマリキー】
 column_varchar01
 column_int02
 column_varchar02

■tbl_test02
 pk_id2【プリマリキー】
 test01_pk(tbl_test01.pk_idが入る)
 column_varchar21
 column_int22
 column_varchar22

「tbl_test02」の項目「test01_pk」には「tbl_test01」のプライマリキー「pk_id」が入ります。
つまり「tbl_test01」と「tbl_test02」の関係は「1対多」です。
※tbl_test01.pk_id = tbl_test02.test01_pk

次にテーブルのモデルをそれぞれ作成しますφ(--)

■Model_Test01
<?php
class Model_Test01 extends \Orm\Model
{
    //使用するtable
    protected static $_table_name = "tbl_test01";

    //プライマリキー
    protected static $_primary_key = array('pk_id');

    //フィールド名
    protected static $_properties = array(
        'pk_id',
        'column_varchar01',
        'column_int02',
        'column_varchar02'
    );
}

■Model_Test02
<?php
class Model_Test02 extends \Orm\Model
{
    //使用するtable
    protected static $_table_name = "tbl_test02";

    //プライマリキー
    protected static $_primary_key = array('pk_id2');

    //フィールド名
    protected static $_properties = array(
        'pk_id2',
        'test01_pk',
        'column_varchar21',
        'column_int22',
        'column_varchar22'
    );
}

この2つのモデルにテーブルの関連性

「tbl_test01」と「tbl_test02」の関係は「1対多」
※tbl_test01.pk_id = tbl_test02.test01_pk

を表現するのが「$_has_one」とか「$_has_many」とか(以下略)なのだそうな。

モデル……と言うよりはテーブル間の関連性を表現すると
「tbl_test01」のモデル「Model_Test01」はこんな感じになりますφ(--)

■Model_Test01
<?php
class Model_Test01 extends \Orm\Model
{
    //使用するtable
    protected static $_table_name = "tbl_test01";

    //プライマリキー
    protected static $_primary_key = array('pk_id');

    //フィールド名
    protected static $_properties = array(
        'pk_id',
        'column_varchar01',
        'column_int02',
        'column_varchar02'
    );

    protected static $_has_many = array('hoge' => array(
        'model_to' => 'Model_Test012',
        'key_from' => 'pk_id',
        'key_to' => 'test01_pk',
        'cascade_save' => true,
        'cascade_delete' => false,
    ));

}

まず「$_has_many」は「自分が1に対して相手は複数紐づきますよ~」の意味です。
「hoge」はその関係性に付けた名前です。
「model_to」は紐づく相手のモデル名ですね。
「key_from」は結合条件となる項目の自分側です。
「key_to」は結合条件となる項目の相手側です。
「cascade_save」「cascade_delete」はカスケードうんちゃららしいですが、
ぶっちゃけよく分かりません。
マニュアルに書いてあったので決まり文句的に書いてあります。

これで「Model_Test01(tbl_test01)」側はOKです。

次は「Model_Test02(tbl_test02)」側に関係性を書きます。
えっ?「Model_Test02」にも書くの?と思うかもしれませんが、書きます。
「Model_Test02」には「私はModel_Test01の子分です~」と書くのです。
小難しく言うと、従属側の定義ですかね。こんな感じφ(--)

■Model_Test02
<?php
class Model_Test02 extends \Orm\Model
{
    //使用するtable
    protected static $_table_name = "tbl_test02";

    //プライマリキー
    protected static $_primary_key = array('pk_id2');

    //フィールド名
    protected static $_properties = array(
        'pk_id2',
        'test01_pk',
        'column_varchar21',
        'column_int22',
        'column_varchar22'
    );

    protected static $_belongs_to = array('hoge' => array(
        'model_to' => 'Model_Test01',
        'key_from' => 'test01_pk',
        'key_to' => 'pk_id',
        'cascade_save' => true,
        'cascade_delete' => false,
    ));

}

「$_belongs_to」は「自分が紐付けられる側ですよ~」の意味です。
機械的に「$_has_one、$_has_manyの反対側」と覚えても構いません。
「hoge」はその関係性に付けた名前です。
「model_to」は紐づけられた親分のモデル名ですね。
「key_from」は……って「$_has_many」のときと同じなので省略します。

これでモデル間の関連性の記述は完了です。
Model_Test01(tbl_test01)とModel_Test02(tbl_test02)は
「1対多」(tbl_test01.pk_id=tbl_test02.test01_pk)の関係なんだな~と
無事に定義されました。

あとはコントローラ側でゲシゲシ使えばOK(--)ノ

例えばこんな感じのコードを実行するとφ(--)

$result = Model_Test01::find('all', array('related' => array('hoge')));
var_dump($result);

こんな感じのSQLが発行されますφ(--)

SELECT (中略) FROM `tbl_test01` AS `t0` LEFT JOIN `tbl_test02` AS `t1` ON (`t0`.`pk_id` = `t1`.`test01_pk`)

そして、いろいろ端折るけどこんな感じの結果が得られますφ(--)

array(16) {
  [1]=>
  object(Model_Test01)#26 (10) {
    ["_data":protected]=>
    array(4) {
      ["pk_id"]=>
      string(1) "1"
      ["column_varchar01"]=>
      string(9) "あああ"
      ["column_int02"]=>
      string(2) "10"
      ["column_varchar02"]=>
      string(9) "いいい"
    }
    ["_data_relations":protected]=>
    array(1) {
      ["hoge"]=>
      array(2) {
        [1]=>
        object(Model_Test012)#27 (10) {
          ["_data":protected]=>
          array(5) {
            ["pk_id2"]=>
            string(1) "1"
            ["test01_pk"]=>
            string(1) "1"
            ["column_varchar21"]=>
            string(9) "アアア"
            ["column_int22"]=>
            string(2) "20"
            ["column_varchar22"]=>
            string(9) "イイイ"
          }
        }
        [2]=>
        object(Model_Test012)#28 (10) {
          ["_data":protected]=>
          array(5) {
            ["pk_id2"]=>
            string(1) "2"
            ["test01_pk"]=>
            string(1) "1"
            ["column_varchar21"]=>
            string(12) "アアア2"
            ["column_int22"]=>
            string(2) "21"
            ["column_varchar22"]=>
            string(12) "イイイ2"
          }
        }
      }
    }
  }
}

「pk_id」が「1」のデータの中に「hoge」があって、
「hoge」の中には「pk_id2」が「1」のデータと
「pk_id2」が「2」のデータが入っていますね。
Model_Test01のfind()結果、それぞれデータ行の中に、
「hoge」で関係性を定義したModel_Test02のデータが入ってきます。

更新系もこんなコードを実行するとφ(--)

//インスタンス生成
$mt = Model_Test01::forge();

//値設定
$data = array(
    'column_varchar01' => 'かかか',
    'column_int02' => 11,
    'column_varchar02' => 'ききき',
);
$mt->set($data);

//サブテーブルの方の値設定
$hoge = new Model_Test02();
$data2 = array(
    'column_varchar21' => '2かかか',
    'column_int22' => 112,
    'column_varchar22' => '2ききき',
);
$hoge->set($data2);

//関連するモデルを設定
$mt->hoge[] = $hoge;

//保存
if(!$mt->save()){
    print "保存失敗";
}else{
    print "保存成功";
}

「tbl_test01」「tbl_test02」両方にデータを突っ込んでくれます。

今回は「$_has_many」「$_belongs_to」を例に挙げましたが
「$_has_one」も考え方は一緒ですよ。

「$_many_many」は……よく分からんけど、使わない方が無難だと思います。

ちなみに関連性を書く項目はこんな感じねφ(--)

$_has_one → 1対1
$_has_many → 1対多
$_belongs_to → 多対1、1対1($_has_one、$_has_manyの反対側)
$_many_many → 多対多

完了\(--)/
スポンサーリンク
 
このエントリーをはてなブックマークに追加 

category:FuelPHP  thema:パソコンな日々 - genre:コンピュータ  Posted by ササキマコト 

  関連記事