如何在CakePHP中的第三个n..n(hasAndBelongsToMany)关系中连接两个表?
我有一个n...n
结构两个表,makes
和models
。到目前为止没有问题。如何在CakePHP中的第三个n..n(hasAndBelongsToMany)关系中连接两个表?
在第三个表(products
),如:
id
make_id
model_id
...
我的问题是创建包含一个specifi make
产品我ProductsController
内部的观点只是我们做的模型:
我认为这可以工作:
var $uses = array('Make', 'Model');
$this->Make->id = 5; // My Make
$this->Make->find(); // Returns only the make I want with it's Models (HABTM)
$this->Model->find('list'); // Returns ALL models
$this->Make->Model->find('list'); // Returns ALL models
所以,如果我想使用list
传递给我的视图中创建单选按钮我会做一个foreach()
我make
阵列找到所有车型的标题,并创建一个新的数组,并通过$this->set()
发送到视图。
$makeArray = $this->Make->find();
foreach ($makeArray['Model'] as $model) {
$modelList[] = $model['title'];
}
$this->set('models', $models)
有没有更简单的方法来获取列表而不强调make
阵列。在我的应用程序中开发这样的场景将是一个普遍的任务。
在此先感谢您的任何提示!
该溶液可以与在模型中的habtm阵列使用with
操作来实现。
使用with
可以定义“中间”表所示:
$habtm = " ...
'with' => 'MakeModel',
... ";
并在内部,在模型或控制器,你可以发布到find
方法的条件。
这里是我的提示:在尝试使用Cake库重新构建之前,尝试使用常规SQL编写查询。实质上,你正在做很多额外的工作,数据库可以为你做。 你的方法(作秀 - 不好SQL):
SELECT * FROM makes, models, products WHERE make_id = 5
你没有考虑到的关系(除非蛋糕自动神奇地理解表之间的关系)
你可能寻找将这些东西连接在一起的东西:
SELECT models.title FROM models
INNER JOIN products
ON products.model_id = models.model_id
AND products.make_id = 5
希望这是一个正确方向的微调?
所有不同的Make-> find()和Model-> find()调用都是完全独立的。即使Make-> Model-> find()与Model-> find()相同,Cake也不会以任何方式记住或考虑您在其他模型中已经找到的内容。您要查找的是一样的东西:
$this->Product->find('all', array('conditions' => array('make_id' => 5)));
退房设置::提取物()用于从$这个 - > Make->找到()
结果得到的模型标题的列表方法
从您的评论中判断,您所要求的是如何从某个模型中获得结果,其中的条件在HABTM相关模型中。即你通常会用原始SQL中的JOIN语句来做这件事。
目前这是Cake的几个弱点之一。有不同的策略来解决这个问题。
-
有相关的B型回归模型A可能的候选人的所有ID,然后做了第二次查询的型号AIE:
$this->ModelB->find('first', array('conditions' => array('field' => $condition))); array( ['ModelB'] => array(...), ['ModelA'] => array( [0] => array( 'id' => 1 ) )
现在你有属于MODELA的所有ID数组到符合您的条件的ModelB,您可以使用Set :: extract()轻松提取这些条件。基本上相当于
SELECT model_a.id FROM model_b JOIN model_a WHERE model_b.field = xxx
。接下来,您找MODELA:$this->ModelA->find('all', array('conditions' => array('id' => $model_a_ids)));
这将产生
SELECT model_a.* FROM model_a WHERE id IN (1, 2, 3)
,这是做JOIN语句的一种迂回的方式。如果你需要一个以上的相关模型的条件下,重复,直到你有MODELA所有的ID,SQL将使用所有的IDS(WHERE id IN (1, 2, 3) AND id IN (3, 4, 5)
)的交叉点。 如果你只需要在ModelB一个条件,但要检索MODELA,只需搜索ModelB。 Cake会为你自动检索相关的ModelAs(见上文)。你可能需要再次Set :: extract(),但这可能已经足够了。
您可以用上面的方法,并与Containable behaviour结合起来,并得到了结果的更多控制。
如果一切都失败或上述方法产生的开销过大,您仍然可以使用
$this->Model->query()
编写自己的原始SQL。如果你坚持Cake SQL标准(正确命名表FROM model_as AS ModelA
)Cake仍然会正确地后处理你的结果。
希望这会让您朝正确的方向发展。
好吧,我知道了,但是,我有品牌和型号之间的n ... N的关系。请问我写的所有n ... N条件下,像makes.id = make_models.make_id和make_models.model_id = models.id ......等等......我的意思是...有一个HABTM ......可我用那个? – 2008-09-22 13:55:12