CakePHP中基于三级关系查询数据

发布于 2024-08-04 18:40:28 字数 171 浏览 4 评论 0原文

我设置了以下关系:

A HABTM B
B belongsTo C
C hasMany B

现在,对于给定的 A,我需要所有 C 以及附加的 B。我可以编写 SQL 查询,但是正确的 CakePHP 方法是什么?我应该在哪个模型上调用什么方法以及使用哪些参数?

I have the following relationships set up:

A HABTM B
B belongsTo C
C hasMany B

Now, for a given A, I need all C with the B's attached. I can write the SQL queries, but what's the proper CakePHP way? What method do I call on which model, and with which parameters?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风吹雪碎 2024-08-11 18:40:28

我会同意 Aziz 的答案,并简单地处理传入的数据。如果您需要 C 作为您的主要模型,那么您将不得不做一些解决方法。 Cake 在相关模型上的条件方面还不是很好,尤其是在删除了第三代表兄弟类型的查询上。它通常只对belongsTo或hasMany关系进行实际的JOIN查询;但不是在 HABTM 关系上,而是在单独的查询中获得的关系。这意味着您不能在相关 HABTM 模型中包含条件。

那么你最好的选择可能是这样的:

// get related records as usual with the condition on A, limit to as little data as necessary
$ids = $this->A->find('first', array(
    'conditions' => array('A.id' => 'something'), 
    'recursive'  => 2,
    'fields'     => array('A.id'),
    'contain'    => array('B.id', 'B.c_id', 'B.C.id') // not quite sure if B.C.id works, maybe go with B.C instead
));

// find Cs, using the ids we got before as the condition
$Cs = $this->C->find('all', array(
    'conditions' => array('C.id' => Set::extract('/B/C/id', $ids)),
    'recursive   => 1
);

请注意,这会产生大量查询,因此它并不是真正的最佳解决方案。编写自己的 SQL 实际上可能是最简洁的方法。

编辑:

或者,您可以 重新绑定您的动态关联以使它们具有Many/belongsTo关系,最有可能使用A和B的连接表/模型。这可能使您能够更轻松地在相关模型上使用条件,但在以下情况下获取C仍然很棘手条件在A上。

I'd go with Aziz' answer and simply process the data as it comes in. If you need C to be your primary model though, you'll have to do a little workaround. Cake is not terrifically good with conditions on related models yet, especially on removed 3rd cousins kind of queries. It usually only does actual JOIN queries on belongsTo or hasMany relations; not on HABTM relations though, those it gets in separate queries. That means you can't include conditions on related HABTM models.

Your best bet then might be something like this:

// get related records as usual with the condition on A, limit to as little data as necessary
$ids = $this->A->find('first', array(
    'conditions' => array('A.id' => 'something'), 
    'recursive'  => 2,
    'fields'     => array('A.id'),
    'contain'    => array('B.id', 'B.c_id', 'B.C.id') // not quite sure if B.C.id works, maybe go with B.C instead
));

// find Cs, using the ids we got before as the condition
$Cs = $this->C->find('all', array(
    'conditions' => array('C.id' => Set::extract('/B/C/id', $ids)),
    'recursive   => 1
);

Note that this produces quite a bunch of queries, so it's not really an optimal solution. Writing your own SQL might actually be the cleanest way.

EDIT:

Alternatively, you could re-bind your associations on the fly to make them hasMany/belongsTo relationships, most likely using the join table/model of A and B. That might enable you to use conditions on related models more easily, but it's still tricky to fetch Cs when the condition is on A.

段念尘 2024-08-11 18:40:28
$this->A->find(
   'first', 
   array('conditions'=>array('id'=>'someword'), 
   'recursive'=>2)
);

像这样?

$this->A->find(
   'first', 
   array('conditions'=>array('id'=>'someword'), 
   'recursive'=>2)
);

like this?

时光病人 2024-08-11 18:40:28

这可能有用

$this->C->find('all',
array('conditions'=>array('id'=>'someword','B.aid'=>$a.id)));

this might work

$this->C->find('all',
array('conditions'=>array('id'=>'someword','B.aid'=>$a.id)));
青朷 2024-08-11 18:40:28

我会想到“可控制”行为(http://book.cakephp.org/view/ 474/Containable)...在查找相关数据方面提供了很多控制。

I'd think of "Containable" behaviour (http://book.cakephp.org/view/474/Containable)... gives a lot control on finding related data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文