テーブル結合 | Database

例えば新着記事を表示する時、その記事のブログ名も表示したいことがあります。そのような時は記事にブログをくっつけて取得してしまえば楽です。
$articles = finder("Article")->innerJoin("Blog")->sort("Article.added", "desc")->limit(10)->fetchAll();
foreach ($articles as $anArticle) {
  echo $anArticle->title . "(" . $anArticle->Blog->title . ")";
}
上記は推奨するカラム名規約に乗っ取っている場合のコーディング例です。(articleテーブルのblog_idがblogテーブルのidカラムを参照しています)
そうでない場合、例えばarticleテーブルのfoo_idがblogテーブルのbar_idを参照しているのなら、下記のようにコーディングしてください。
$joinKey = array("id" => "bar_id", "fkey" => "foo_id");
$articles = finder("Article")->innerJoin("Blog", $joinKey)->sort("Article.added", "desc")->limit(10)->fetchAll();
コーディング量は多くなってしまいますが、必要なカラムだけ指定した方がパフォーマンスに優れます。
$aFinder = finder("Article");
$aFinder->p(array(
  "Article" => array("id", "title", "added"),
  "Blog" => array("id", "title"),
));

$articles = $aFinder->innerJoin("Blog", $joinKey)->sort("Article.added", "desc")->limit(10)->fetchAll();
これまでで分かるように、結合したモデルはそのモデル名でアクセスすることができます。しかし、同じモデルを参照するカラムが複数存在する場合、モデル名が重複してしまうことになります。
例えばユーザとユーザのつながりを表すテーブルが存在があるとします。

from_user_idto_user_id...
12...
31...
21...
このテーブル(user_pairとする)を元にユーザ名を表示するために、下記のようなコードを書いてしまうと、Userにアクセスできなくなります。Userが重複しているからです。
$upFinder = finder("UserPair");
$upFinder->innerJoin("User", array("id" => "id", "fkey" => "from_user_id"));
$upFinder->innerJoin("User", array("id" => "id", "fkey" => "to_user_id"));
$pairs = $upFinder->fetchAll();

foreach ($pairs as $pair) {
  $pair->User;  // NG
}
この問題を回避するために、innerJoinメソッドの第3引数でモデル名のエイリアス(別名)を指定します。
$upFinder = finder("UserPair");
$upFinder->innerJoin("User", array("id" => "id", "fkey" => "from_user_id"), "FromUser");
$upFinder->innerJoin("User", array("id" => "id", "fkey" => "to_user_id"), "ToUser");
$pairs = $upFinder->fetchAll();

foreach ($pairs as $pair) {
  echo $pair->FromUser->name;
  echo $pair->ToUser->name;
}
なお、別名を付けた場合は、取得するカラムの指定・条件・並び替えの時のモデル名には別名を指定してください。
$finder->p(array(
  "AliasName" => array(...)
));

$finder->ge("AliasName.added", $date);
$finder->sort("AliasName.added", "desc");
これまでinnerJoinを用いてきましたが、leftJoinやrightJoinメソッドもあります。

先ほど、新着記事と、その記事が含まれるブログのタイトルを表示しました。さらに、そのブログの管理者(投稿者・ユーザ)の名前も表示したい場合もあるかもしれません。
その場合は、まずブログにユーザを結合したリレーションオブジェクトを作り、それを結合します。
$bRel = rel("Blog")->innerJoin("User");
$articles = finder("Article")->innerJoin($bRel)->sort("Article.added", "desc")->limit(10)->fetchAll();
foreach ($articles as $anArticle) {
  echo $anArticle->title . "(" . $anArticle->Blog->title . ") [" . $anArticle->Blog->User->name . "]";
}
innerJoinメソッド(またはleftJoin, rightJoinメソッド)にリレーションオブジェクトを渡す場合でも、モデル名を渡す時と同様に、第2引数で結合カラムを、第3引数でエイリアスを指定することが可能です。
4つ以上結合する場合や、2つ3つでもよく結合する場合は、ビューを作ってしまった方が良いと思います。モデル(ActiveRecord)でビューを扱う方法はこちらを参照してください。