CakePHP2.x リレーションシップ(アソシエーション)のまとめ…

さて表題通り、CakePHPにはモデル間のアソシエーションを定義することでリレーショナルデータベースを構築できます。
CakePHP には4つのアソシエーションが用意されています。hasOne, hasMany, belongsTo, そして hasAndBelongsToMany (HABTM) です。
Cookbookには以下のように説明がされています。

hasOne(1 対 1)
hasMany(1 対 多)
belongsTo(多 対 1)
hasAndBelongsToMany(多 対 多)

言い換えると以下のような感じになる。

hasOne:相手テーブルに、自分テーブル.idの外部キーをもっている(この外部キーはユニークである)
hasMany:相手テーブルに、自分テーブル.idの外部キーをもっている(この外部キーは複数ある)
belongsTo:自テーブルに、相手テーブル.idの外部キーをもっている
hasAndBelongsToMany:中間テーブル テーブル1とテーブル2の情報をもっている

※「hasOne」と「hasMany」の関連性はほぼ同じですが、ユーニークかじゃないかの違いみたいです。

少し具体的な部分をCakePHPのCookbookを見ながら理解を深めていきます。

20160617-pict01


【hasOne】

class User extends AppModel {
    public $hasOne = array(
        'Profile' => array(
            'className' => 'Profile',
            'conditions' => array('Profile.published' => '1'),
            'dependent' => true
        )
    );
}

UserテーブルとProfileテーブルがあります。
Profileテーブルは、1つのUser.id(ユーザーid)を持っていることになります。
hasOneですので、 プロフィール情報は1つユーザーに1つしかない。当たり前ですが、このような関係をhasOneで定義します。

———

20160617-pict02


【hasMany】

class User extends AppModel {
    public $hasMany = array(
        'Comment' => array(
            'className' => 'Comment',
            'foreignKey' => 'user_id',
            'conditions' => array('Comment.status' => '1'),
            'order' => 'Comment.created DESC',
            'limit' => '5',
            'dependent' => true
        )
    );
}

UserテーブルとCommentテーブルがあります。
Commentテーブルは、ユーザーid情報を持っています。Commentテーブルには同じユーザーidを持っているレコードが複数存在します。
1ユーザーが複数のコメントを投稿出来るため、ユーザーとコメントの関連性はhasManyで定義することになります。

———

20160617-pict03


【belongsTo】

class Profile extends AppModel {
    public $belongsTo = array(
        'User' => array(
            'className' => 'User',
            'foreignKey' => 'user_id'
        )
    );
}

さてbelongsToの定義です。
先ほどhasOneの定義で、UserモデルからProfileモデルにアクセスできるようになりました。
視点を逆にしてみます。プロフィールテーブルにはユーザーid(外部キー)を含んでいるため、Userテーブルに属しているということになります。
その場合にProfileテーブルは、UserテーブルとbelongsToの関係で定義することになります。

———

20160617-pict04


【hasAndBelongsToMany (HABTM)】

class Recipe extends AppModel {
    public $hasAndBelongsToMany = array(
        'Ingredient' =>
            array(
                'className' => 'Ingredient',
                'joinTable' => 'ingredients_recipes',
                'foreignKey' => 'recipe_id',
                'associationForeignKey' => 'ingredient_id',
                'unique' => true,
                'conditions' => '',
                'fields' => '',
                'order' => '',
                'limit' => '',
                'offset' => '',
                'finderQuery' => '',
                'with' => ''
            )
    );
}

最後にhasAndBelongsToManyです。こちらは中間テーブルとなります。
上記を例にすると、Recipeテーブル、Ingredientテーブルがあり、それをRecipe_Ingredientで紐づけるイメージです。

ということでCakePHP2.xのアソシエーションについてメモしました。
皆さんもご存知の通りすでにCakePHPは3系がリリースされています。
自分はこれから3系についても勉強をしていきますが、ファイル構成を眺めただけでも大分2系とは違いがありそうです。
ですがきっとこれまで勉強していた2系がベースとして役立つと思います。
新しい技術習得に努めていきたいと思います。

間違っていることや分かりやすい考え方、3系での違い等の情報があれば、ぜひコメントを残していただけると嬉しいです。
よろしくお願い致します。m(_ _)m