使用Containable强制连接

时间:2013-06-21 15:26:39

标签: php cakephp

这是我的联想:

  • 收藏的belongsTo相册
  • 专辑属于艺术家
  • 艺术家HABTM部分

基本上我要做的是使用强制连接的可包含行为。如果用户正在查看他的所有收藏夹,我想要包含与收藏夹相关联的相册,与该相册相关联的艺术家以及艺术家所属的部分。这很容易处理可容纳的行为,如下所示:

$this->Favorite->find('all', array(
    'contain' => array(
        'Album' => array(
            'Artist' => array(
                'Section'
            )
        )
    )
));

我的问题是我还希望用户能够按艺术家和专辑名称进行搜索。不幸的是我不能这样做:

$this->Favorite->find('all', array(
    ...
    'conditions' => array(
        'OR' => array(
            'Artist.name LIKE' => '%' . $this->request->query['query'] . '%',
            'Album.name LIKE' => '%' . $this->request->query['query'] . '%'
        )
    )
));

为什么呢?因为Cake只会执行第一次加入Album,它会对艺术家进行单独查询。所以我必须做的是删除可包含的行为,并手动进行连接,以便我可以按照艺术家和专辑名称进行搜索,如下所示:

$this->Favorite->find('all', array(
    'fields' => array(
        'Favorite.*',
        'Album.*',
        'Artist.*'
    ),
    'conditions' => array(
        'OR' => array(
            'Artist.name LIKE' => '%' . $this->request->query['query'] . '%',
            'Album.name LIKE' => '%' . $this->request->query['query'] . '%'
        )
    ),
    'joins' => array(
        array(
            'table' => 'albums',
            'alias' => 'Album',
            'type' => 'left',
            'foreignKey' => false,
            'conditions' => array('Album.id = Favorite.album_id')
        ),
        array(
            'table' => 'artists',
            'alias' => 'Artist',
            'type' => 'left',
            'foreignKey' => false,
            'conditions' => array('Artist.id = Album.artist_id')
        )
    )
));

这非常适合按艺术家和专辑名称搜索。我的问题是我还想要包含艺术家所属的部分。我不能再添加contain密钥,因为Cake会复制Album联接,这会引发'not unique table alias'错误。

我的问题是,获得与每位艺术家相关的部分的最佳或最有效的方法是什么,而不必遍历每个收藏夹并为每个收藏夹执行单独的查询?或者这是我必须采取的路线?

2 个答案:

答案 0 :(得分:0)

您无法将containablejoins混合搭配,因此您需要做一些稍微不同的事情。

使用bindModel动态创建一些其他关系,然后在使用标准关系forableable时可以使用新关系作为条件。

答案 1 :(得分:-1)

好吧,我已经设法用一个(肮脏的)黑客来解决这个问题:

$this->Favorite->find('all', array(
    'contain' => array(
        'Album' => array(
            'Artist' => array(
                'Section'
            )
        )
    ),
    'conditions' => array(
        'OR' => array(
            '(SELECT name FROM artists WHERE id = Album.artist_id) LIKE' => '%' . $this->request->query['query'] . '%',
            'Album.name LIKE' => '%' . $this->request->query['query'] . '%'
        )
    )
));