アソシエーション

アソシエーション

アソシエーションはテーブルオブジェクトの initialize() の中で定義される。関連付けたいテーブルのエイリアスをメソッドに渡す。デフォルトでは

<?php
namespace App\Model\Table;
use Cake\ORM\Table;

class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsTo('Authors');
    }
}
?>

関連付けたいテーブルのエイリアスをbefongsToメソッドに渡す。上の例では規約によりauthersテーブルと紐づく。

<?php
class CategoriesTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasMany('SubCategories', [
            'className' => 'Categories'
        ]);

        $this->belongsTo('ParentCategories', [
            'className' => 'Categories'
        ]);
    }
}
?>

classNameオプションで関連づくモデルの名前を指定し、エイリアスとしては異なる名称を渡すときの例。このように、同一テーブルを異なるエイリアスとして定義したりできる。

hasOne

<?php
class UsersTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasOne('Address');
    }
}
?>

hasOneで使用できるオプション

  • className: 当該のモデルに関連付けられるモデルのクラス名。
  • foreignKey: 相手側のテーブル上の外部キーの名前。デフォルトでは当該モデル名_id 'user_id'など。
  • bindingKey: foreignKey での紐付けに使用される、当該のテーブルのカラム名。デフォルトでは主キーが使われる。
  • conditions: ['Addresses.primary' => true] のような find() 互換の条件の配列。
  • joinType: SQL クエリーで使われる結合の種別。デフォルトはLEFT。
  • dependent: trueのとき、エンティティーが削除されたときに関連付けられたモデルのレコードも削除される。
  • propertyName: 関連付けられたテーブルからソースのテーブルの結果にデータを埋める際のプロパティー名。デフォルトでは'user'など。
  • strategy: クエリーで使うためのストラテジー。既定は 'join'。他に'select'が有効。
  • finder: 関連付けられたレコードを読み込む時に使われるファインダーメソッド。

belongsTo

<?php
class AddressesTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsTo('Users');
    }
}
?>

belongsToで使用できるオプション

  • className: 当該のモデルに関連付けられるモデルのクラス名。
  • foreignKey: 当該テーブル上の外部キーの名前。デフォルトでは相手側モデル名_id 'user_id'など。
  • bindingKey: foreignKey での紐付けに使用される、相手側のテーブルのカラム名。デフォルトでは主キーが使われる。
  • conditions: ['Users.active' => true] のような find() 互換の条件の配列。
  • joinType: SQL クエリーで使われる結合の種別。デフォルトはLEFT。
  • propertyName: 関連付けられたテーブルからソースのテーブルの結果にデータを埋める際のプロパティー名。デフォルトでは'user'など。
  • strategy: クエリーで使うためのストラテジー。既定は 'join'。他に'select'が有効。
  • finder: 関連付けられたレコードを読み込む時に使われるファインダーメソッド。

hasMany

<?php
class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasMany('Comments');
    }
}
?>

hasManyで使用できるオプション

  • className: 当該のモデルに関連付けられるモデルのクラス名。
  • foreignKey: 相手側のテーブル上の外部キーの名前。デフォルトでは当該モデル名_id 'article_id'など。
  • bindingKey: foreignKey での紐付けに使用される、当該のテーブルのカラム名。デフォルトでは主キーが使われる。
  • conditions: ['Comments.visible' => true] のような find() 互換の条件の配列。
  • sort: ['Comments.created' => 'ASC'] のような find() 互換の order 句の配列。
  • dependent: trueのとき、エンティティーが削除されたときに関連付けられたモデルのレコードも削除される。
  • propertyName: 関連付けられたテーブルからソースのテーブルの結果にデータを埋める際のプロパティー名。デフォルトではアソシエーションの名前の複数形'comments'など。
  • strategy: クエリーで使うためのストラテジー。既定は 'select'。他に'subquery'が有効で、これは IN のリストを等価のサブクエリーに置き換える。
  • finder: 関連付けられたレコードを読み込む時に使われるファインダーメソッド。

belongsToMany

<?php
// src/Model/Table/ArticlesTable.php の中で
class ArticlesTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Tags');
    }
}

// src/Model/Table/TagsTable.php の中で
class TagsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Articles');
    }
}
?>

belongsToManyで使用できるオプション

  • className: 当該のモデルに関連付けられるモデルのクラス名。
  • joinTable: このアソシエーションで使われる結合テーブルの名前。
  • foreignKey: 結合テーブル上の当該のモデルを参照する外部キーの名前。デフォルトでは当該モデル名_id 'article_id'など。
  • bindingKey: foreignKey での紐付けに使用される、当該のテーブルのカラム名。デフォルトでは主キーが使われる。
  • targetForeignKey: 結合モデル上の対象モデルを参照する外部キーの名前。デフォルトでは当該モデル名_id 'article_id'など。
  • conditions: ['Comments.visible' => true] のような find() 互換の条件の配列。
  • sort: ['Comments.created' => 'ASC'] のような find() 互換の order 句の配列。
  • dependent: falseのとき、エンティティーが削除されても結合テーブルのレコードは削除されない。
  • through: 結合テーブルで使用する Table インスタンスエイリアス。これにより、結合テーブルのキーのカスタマイズが可能になる。詳細は次節。
  • propertyName: 関連付けられたテーブルからソースのテーブルの結果にデータを埋める際のプロパティー名。デフォルトではアソシエーションの名前の複数形'tags'など。
  • strategy: クエリーで使うためのストラテジー。既定は 'select'。他に'subquery'が有効で、これは IN のリストを等価のサブクエリーに置き換える。
  • finder: 関連付けられたレコードを読み込む時に使われるファインダーメソッド。
throughオプション

結合テーブルに追加の情報をもたせたり、規約から外れる結合カラムを使用する場合、throughオプションを定義する必要がある。

Student BelongsToMany Course
Course BelongsToMany Student

このようなアソシエーションがあるとき、結合テーブルは以下のカラムで事足りるが、

id | student_id | course_id

このように追加の情報をもたせたい場合もある。

id | student_id | course_id | days_attended | grade

そうした場合、結合テーブルのクラスを定義し(必要であれば追加の情報をもたせるなどの設定を行い)、throughオプションで結合テーブルを指定する。

<?php
class StudentsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Courses', [
            'through' => 'CoursesMemberships',
        ]);
    }
}

class CoursesTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsToMany('Students', [
            'through' => 'CoursesMemberships',
        ]);
    }
}

class CoursesMembershipsTable extends Table
{
    public function initialize(array $config)
    {
        $this->belongsTo('Students');
        $this->belongsTo('Courses');
    }
}
?>