割とはまったのでメモ
同じテーブルへのアソシエーション
前提:コメントへのレスコメントができる機能を想定する。
簡易的な例のため、コメントとレスコメントは__1対1__の関係にあると仮定。
CakePHPにおけるアソシエーションの記載
1対1の関係はhasOne
メソッドによって設定する。
このメソッドの__第一引数__が__SQLにおけるテーブルのエイリアス(別名)__になる。
class CommentsTable extends Table
{
public function initialize(array $config)
{
$this->hasOne('ResponseComment', [// ResponseCommentがSQL中のCommentsテーブルの別名になる。
'className' => 'Comments' // 実際に扱うテーブル(テーブルクラス)を指定する
])
->setProperty('responseComment')// $comment->responseComment のような記述でレスポンスコメントを取得できるようにする
->setJoinType('INNER'); // ここでは内部結合を指定する。
}
}
コメントと紐付いたレスをまとめて取得する。
$this->Comments
->find()// SQLにおけるSELECT文の発行
->where(['Comments.id' => $id])// WHERE句の追加 ←ここがポイント
->contain(['ResponseComment']);// 紐付いたレスも取得する。
上記は以下のようなSQLに変換される。(:ct0
にプログラム中の$id
が代入される)
SELECT
Comments.id
FROM comments Comments
INNER JOIN comments ResponseComment ON
(
Comments.id=ResponseComment.id
)
WHERE
(
Comments.id = :c0 -- プログラム中のwhere()メソッドが別名付きにしてくれる
)
ポイント
プログラム中のwhere()
がポイントで、単にid
と書くと
○ ResponseComment
のidなのか
○ Comments
のidなのか
分からない。そのため、Comments.id
を渡してあげる。
※単にid
と記述するとSQL実行時にwhere clause is ambiguous
エラーが出力される。