Containable 不会使用 HABTM 和 HABTM 过滤二级模型。有很多

发布于 2024-10-04 20:49:57 字数 2963 浏览 4 评论 0原文

我拥有的:

"A" HABTM "C" HABTM "A" through join table "B"
"A" hasMany "B" belongsTo "A"
"C" is ordered by a "B" field

我想要的:

// result:
[0] => array( 
    A => array( /* single model's fields I still need*/ ),
    C => array(
        [0] => array( C.field1, C.field2, ... /* Model C fields*/ ), 
        [1] => array( C.field1, C.field2, ... )
    )
) 

我尝试过的:

// this gives me data I don't need:
A->find('all', array( 'conditions' => array( 'id' => $id ) ) )
// result:
[0] => array( 
    A => array( /* single model's fields I need*/ ),
    B => array( /* I DON'T NEED */
        [0] => array( ... )
        [1] => array( /* ... etc, tons records I don't need */ )
    ),
    C => array(
        [0] => array( C.field1, C.field2, ... /* I need these fields*/ 
            [B] => array( /* I DON'T NEED */ )
        ),
        [1] => array( C.field1, C.field2, ...  )
            [B] => array( /* ... etc, each has a model B I don't need ... */)
        )
    )
)

使用 Containable,我可以大大减少查询,但是有仍然关联的模型cruft:

// this is a little better
A->find('all', array( 
    'conditions' => array( 'id' => $id ),
    'contain' => array( 'C' )
))
// result:
[0] => array( 
    A => array( /* single model's fields I still need*/ ),
    C => array(
        [0] => array( C.field1, C.field2, ... /* I still need Model C fields*/ 
            [B] => array( /* I still DON'T need this Model's fields */ )
        ),
        [1] => array( C.field1, C.field2, ... 
            [B] => array( /* ... still has unneeded model B */)
        )
    )
)

NB1:我已阅读这个这个这本书中的,以及 这个这个< /a>.

NB2:我也尝试过

C->recursive = -1 // no effect

C->unbindModel(array('hasAndBelongsToMany'=>A)) // no effect

A->find('all', array(                    // not what I want, but it's still 
    'conditions' => array('id' => $id),  // odd that this doesn't filter C's 
    'contain' => array('A.B')));         // fields out. same as second result

A->find('all', array(                    // also not what I want, but it's 
    'conditions' => array('id' => $id),  // weird that this doesn't filter B's 
    'contain' => array('A.B.field')));   // fields at all; 

What I have:

"A" HABTM "C" HABTM "A" through join table "B"
"A" hasMany "B" belongsTo "A"
"C" is ordered by a "B" field

What I want:

// result:
[0] => array( 
    A => array( /* single model's fields I still need*/ ),
    C => array(
        [0] => array( C.field1, C.field2, ... /* Model C fields*/ ), 
        [1] => array( C.field1, C.field2, ... )
    )
) 

What I've tried:

// this gives me data I don't need:
A->find('all', array( 'conditions' => array( 'id' => $id ) ) )
// result:
[0] => array( 
    A => array( /* single model's fields I need*/ ),
    B => array( /* I DON'T NEED */
        [0] => array( ... )
        [1] => array( /* ... etc, tons records I don't need */ )
    ),
    C => array(
        [0] => array( C.field1, C.field2, ... /* I need these fields*/ 
            [B] => array( /* I DON'T NEED */ )
        ),
        [1] => array( C.field1, C.field2, ...  )
            [B] => array( /* ... etc, each has a model B I don't need ... */)
        )
    )
)

Using Containable, I can cut down the query quite a bit, but there's still associated model cruft:

// this is a little better
A->find('all', array( 
    'conditions' => array( 'id' => $id ),
    'contain' => array( 'C' )
))
// result:
[0] => array( 
    A => array( /* single model's fields I still need*/ ),
    C => array(
        [0] => array( C.field1, C.field2, ... /* I still need Model C fields*/ 
            [B] => array( /* I still DON'T need this Model's fields */ )
        ),
        [1] => array( C.field1, C.field2, ... 
            [B] => array( /* ... still has unneeded model B */)
        )
    )
)

NB1: I've read this, this, and this from the book, as well as this and this.

NB2: I've also tried

C->recursive = -1 // no effect

C->unbindModel(array('hasAndBelongsToMany'=>A)) // no effect

A->find('all', array(                    // not what I want, but it's still 
    'conditions' => array('id' => $id),  // odd that this doesn't filter C's 
    'contain' => array('A.B')));         // fields out. same as second result

A->find('all', array(                    // also not what I want, but it's 
    'conditions' => array('id' => $id),  // weird that this doesn't filter B's 
    'contain' => array('A.B.field')));   // fields at all; 

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

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

发布评论

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

评论(1

诗酒趁年少 2024-10-11 20:49:57

ContainableBehavior 将自动返回映射结果所需的字段。

引用您已经阅读过的页面

$this->Post->find('all', array('contain' => 'Comment.author'));

... // data returned:

[Comment] => Array
    (
        [0] => Array
            (
                [author] => Daniel
                [post_id] => 1
            )
...

如您所见,注释数组
仅包含作者字段(加上
CakePHP 需要的 post_id
绘制结果)。

对于 HABTM 关系,将返回具有关联外键的连接模型,因为 Containable 需要 a_idc_id 字段。我的建议是忽略它并采用您需要的值。如果您愿意,您可以看看 join 因为 Containable 有时会多次查询数据库。但是,关联模型的数据不会像 Containable 那样很好地返回。

The ContainableBehavior will automatically return fields that are required to map results.

Quoting from a page that you already read:

$this->Post->find('all', array('contain' => 'Comment.author'));

... // data returned:

[Comment] => Array
    (
        [0] => Array
            (
                [author] => Daniel
                [post_id] => 1
            )
...

As you can see, the Comment arrays
only contain the author field (plus
the post_id which is needed by CakePHP
to map the results).

In the case of HABTM relationships, the join model with the associated foreign keys is returned, since the a_id and c_id fields are required by Containable. My suggestion is to just ignore it and take the values you need. If you want, you could probably take a look at joins because Containable sometimes queries the DB many, many times. However, the data for associated models won't be returned as nicely as Containable.

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