誰でも私に教えてもらえますか?結合された結果をCakePHPの複数のテーブルから取得する方法(cakePHP mvcアーキテクチャを使用)。たとえば、結合する3つのテーブル(tbl_topics、tbl_items、tbl_votes)があります。それらの関係は次のように定義されています:トピックには多くのアイテムを含めることができ、アイテムには多数の投票を含めることができます。各トピックのすべてのアイテムに対するすべての投票。このためのSQLクエリは以下のようになります。
_SELECT Topic.*, count(Vote.id) voteCount
FROM
tbl_topics AS Topic
LEFT OUTER JOIN tbl_items AS Item
ON (Topic.id = Item.topic_id)
LEFT OUTER JOIN tbl_votes AS Vote
ON (Item.id = Vote.item_id);
_
私の問題は、_$this-><Model Name>->query
_関数を使用して簡単に実行できることですが、これには、必要のないコントローラーでSQLコードを記述する必要があります。これを行う他の方法を見つけようとしています(find()
など)。
$markers = $this->Marker->find('all', array('joins' => array(
array(
'table' => 'markers_tags',
'alias' => 'MarkersTag',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('MarkersTag.marker_id = Marker.id')
),
array(
'table' => 'tags',
'alias' => 'Tag',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array(
'Tag.id = MarkersTag.tag_id',
'Tag.tag' => explode(' ', $this->params['url']['q'])
)
)
)));
nate abeleの記事で言及されているように: link text
ここでは正直に言って、getTopicVotes()のような関数を作成してquery()を呼び出すだけで、モデルに関数を作成した方がずっと楽になると思います。私が考えることができる他のすべての解決策は、それをより複雑にし、したがって醜くするだけです。
編集:
データのサイズに応じて、モデル関係を適切に設定したと仮定すると(トピックhasManyアイテムhasMany投票)、allアイテムを含む簡単なfind( 'all')を実行できます投票してから、次のようにします。
foreach ($this->data as &$topic)
{
$votes = Set::extract('/Topic/Item/Vote', $topic);
$topic['Topic']['vote_count'] = count($votes);
}
ここでは2つのことが重要です。
Find()クエリで「再帰」プロパティを簡単に設定できます。
$result = $this->Topic->find('all', array('recursive' => 2));
または、モデルでContainable動作を使用できます。それからあなたは使うことができます:
$this->Topic->contain(array(
'Item',
'Item.Vote',
));
$result = $this->Topic->find('all');
または
$result = $this->Topic->find('all', array(
'contain' => array(
'Item',
'Item.Vote',
),
));
必要なのは、再帰的な関連付けのサポートです。これは、現在のCakePHPでは不可能です。
いくつかの bindModelトリック を使用して達成できますが
または実験的な RecursiveAssociationBehavior 。
これらのソリューションはどちらも、追加のコードを使用するか、アプリケーションの動作に依存する必要がありますが、純粋なSQLコードを記述したくない場合は、Cakeのページネーション、自動条件を使用できるというメリットがあります。モデルマジックなど。
この回答はすでに提出されていると思いますが、まだこれを求めている人のためにここに投稿しています。結合はfind()メソッドで行うことができ、以下のようになります。
$result = $this->ModelName1->find("all",array(
'fields' => array('ModelName1.field_name','Table2.field_names'), // retrieving fileds
'joins' => array( // join array
array(
'table' => 'table_name',
'alias' => 'Table2',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('ModelName1.id = Table2.id') // joins conditions array
),
array(
'table' => 'table_name3',
'alias' => 'Table3',
'type' => 'inner',
'foreignKey' => false,
'conditions'=> array('Table3.id = Table2.id')
)
)));