【问题标题】:Using Containable with forced joins将 Containable 与强制连接一起使用
【发布时间】:2013-06-21 15:26:38
【问题描述】:

这是我的联想:

  • 最喜欢的属于相册
  • 专辑属于艺术家
  • 艺术家 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 连接,这将引发“非唯一表别名”错误。

我的问题是,什么是最好或最有效的方式来获取与每个艺术家相关联的部分,而不必遍历每个收藏夹并为每个收藏夹执行单独的查询?还是这就是我要走的路?

【问题讨论】:

    标签: php cakephp


    【解决方案1】:

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

    使用bindModel 即时创建一些附加关系,然后您可以将新关系用于条件,同时将标准关系用于可包含。

    【讨论】:

      【解决方案2】:

      好吧,我已经设法通过(肮脏的)黑客解决了这个问题:

      $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'] . '%'
              )
          )
      ));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-11-18
        • 2015-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-29
        相关资源
        最近更新 更多