0

我有n...n两个表的结构,makes并且models. 到目前为止没有问题。

在第三个表 ( products) 中,例如:

id
make_id
model_id
...

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

所以,如果我想使用listto 传递给我的视图来创建单选按钮,我将不得不foreach()在我的make数组中执行一个来查找所有模型标题并创建一个新数组并通过$this->set().

$makeArray = $this->Make->find();
foreach ($makeArray['Model'] as $model) {
    $modelList[] = $model['title'];
}
$this->set('models', $models)

有没有更简单的方法来获取该列表而不会强调make数组。在我的应用程序中开发此类场景将是一项常见任务。

提前感谢您的任何提示!

4

5 回答 5

1

这是我的提示:在尝试使用 Cake 库进行重构之前,尝试用常规 SQL 编写查询。本质上,您正在做很多数据库可以为您做的额外工作。你的方法(只是为了展示 - 不是好的 SQL):

SELECT * FROM makes, models, products WHERE make_id = 5

您没有考虑关系(除非 Cake 自动神奇地理解表的关系)

您可能正在寻找将这些东西连接在一起的东西:

SELECT models.title FROM models 
INNER JOIN products 
  ON products.model_id = models.model_id 
  AND products.make_id = 5

希望这是朝着正确方向的推动?

于 2008-09-22T02:18:32.687 回答
1

从您的评论来看,您要问的是如何从某个模型中获取结果,其中条件位于 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
            )
    )
    

    现在,您拥有了一个包含属于 ModelB 且符合您的条件的 ModelA 的所有 id 的数组,您可以使用 Set::extract() 轻松提取这些 id。基本上相当于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 将使用所有 id 的交集 ( WHERE id IN (1, 2, 3) AND id IN (3, 4, 5))。

  • 如果您只需要 ModelB 上的一个条件但想检索 ModelA,只需搜索 ModelB。Cake 会自动为您检索相关的 ModelAs(见上文)。您可能需要再次 Set::extract() 它们,但这可能已经足够了。

  • 您可以使用上述方法并将其与Containable 行为相结合,以更好地控制结果。

  • 如果所有其他方法都失败了,或者上述方法只会产生过多的开销,您仍然可以使用$this->Model->query(). 如果您坚持 Cake SQL 标准(使用 正确命名表FROM model_as AS ModelA),Cake 仍然会正确地对您的结果进行后处理。

希望这会让您朝着正确的方向前进。

于 2008-10-02T05:24:57.340 回答
0

您所有不同的 Make->find() 和 Model->find() 调用都完全相互独立。甚至 Make->Model->find() 与 Model->find() 相同,Cake 不会以任何方式记住或考虑您在其他模型中已经找到的内容。你正在寻找的是这样的:

$this->Product->find('all', array('conditions' => array('make_id' => 5)));
于 2008-09-22T07:44:49.080 回答
0

查看 Set::extract() 方法,从 $this->Make->find() 的结果中获取模型标题列表

于 2008-09-23T19:40:43.563 回答
0

该解决方案可以通过with在模型上使用 habtm 数组中的操作来实现。

使用with您可以定义“中间”表,如:

$habtm = " ...
  'with' => 'MakeModel',
   ... ";

在内部,在模型或控制器中,您可以向find方法发出条件。

见:http ://www.cricava.com/blogs/index.php?blog=6&title=modelizing_habtm_join_tables_in_cakephp_&more=1&c=1&tb=1&pb=1

于 2009-02-03T20:00:54.697 回答