【问题标题】:find() based on conditions in multiple HABTM relationsfind() 基于多个 HABTM 关系中的条件
【发布时间】:2012-08-18 18:35:01
【问题描述】:

我正在使用 CakePHP 2.1
让我们声明我有以下模型和关系:
PostsbelongsTo Edition
PostsHABTM Editors
PostsHABTM Tags

我从PostsController 推理,我想找到属于某个Edition 的所有Posts,并且Editor.id=55 是相关的,Tag.id=33 是相关的。

我发现了许多示例,其中基于 HABTM 关系上的条件查找Posts 是通过“反转”Editor 的查找方向和原因来完成的。

$this->Editor->find('all',
    array(
        'conditions'=>array('Editor.id'=>55),
        'contain'=>array('Post')
    )
);

不幸的是,这在这里不起作用,因为我想设置多个 HABTM 关系。

同样使用 contain 也不起作用,因为它只切断了一个分支 (editors),但无助于过滤它的父级 (posts)。

我该如何解决这个问题?
我可能需要诉诸临时加入吗?如果是这样,有人可以大致解释我采取什么方法吗?

编辑: 一些伪代码以说明我想要实现的目标:

$this->Post->find('all',
    array('conditions'=>array(
            'Edition.id'=>4,
             // start pseudo code
            'Post.Editor' => 'has at least one related editor with id=55',
            'Post.Tag' => 'has at least one related tag with id=33',
        )
    )
);

亲切的问候, 巴特

编辑解决方案: 在@RichardAtHome 之后,我创建了下面的解决方案。没有(还)使用多个连接条件,但这似乎没有必要:

// Paginate over Cards that belong to current Subscription (belongsTo) AND the User is related to as an Editor (HABTM)
$this->paginate = array(
    'fields' => array('id','title','workingtitle','attachment_count','subscription_id'),
    'joins' => array(
        // create Editor-join
        array(
            'table' => 'cards_users',
            'alias' => 'Editor',
            'type' => 'left',
            'conditions' => array(
                'Editor.card_id = Card.id'
            )
        ), 
        array( 
            'table' => 'users', 
            'alias' => 'User', 
            'type' => 'left',
            'conditions'=> array( 
                'User.id = Editor.user_id'
            ) 
        )
    ),
    'conditions' => array(
        'OR' => array(
            // is Card in current subscription? (straightforward condition)
            array('Card.subscription_id',$subscription_id),
            // is current User assigned as Editor? (condition works with join above)
            array('User.id' => $user['id'])
        )
    ),
    'limit' => 10
);

【问题讨论】:

  • 你真正想要什么?给出你想要的一些粗略的代码图。
  • @arun-jain 我添加了一些伪代码,是否足够清楚?

标签: cakephp cakephp-2.0 conditional-statements has-and-belongs-to-many multiple-conditions


【解决方案1】:

对于这种类型的查询,我通常发现自己构建连接是最简单的,因为 cake 不会连接,它将执行多个查询(从表 a 中选择匹配的行,然后从表 b 中获取匹配的行)。

您的查询需要如下所示:

$this->Post->find('all',
    array(
        'conditions'=>array('Post.edition_id'=>4),
        'joins'=>array(
            array(
                'type'=>'inner',
                'table'=>'posts_editors',
                'alias'=>'PostsEditor',
                'conditions'=>array(
                    'PostsEditor.post_id = Post.id',
                    'PostsEditor.editor_id'=>55 // your criteia for editor id=55
                )
            ),
            array(
                'type'=>'inner',
                'table'='posts_tags',
                'alias'=>'PostsTag',
                'conditions'=>array(
                    'PostsTag.post_id = Post.id',
                    'PostsTag.tag_id'=>33 // your criteria for tag id = 33
                )

            )
        )
    )
);

检查输出的 SQL 以了解此查询在幕后实际执行的操作。

【讨论】:

  • @RichardAtHome 嘿,Richard,你似乎对加入很了解。你能看看这个很烦人,但我有类似的问题吗? -- Go to the Question -- 非常感谢!
【解决方案2】:

试试:

$this->Post->find('all',
        array('conditions'=>array(
                'Edition.id'=>4,
                'Editor.id' => '55',
                'Tag.id' => '33',
            )
        )
    );

【讨论】:

  • 只尝试“Editor.id”条件我得到错误:Error: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Editor.id' in 'where clause'
  • public $hasAndBelongsToMany = array('Editor' => array( 'className' => 'User', 'joinTable' => 'cards_users', 'foreignKey' => 'card_id', 'associationForeignKey' => 'user_id', 'unique' => 'keepExisting', // only users belonging to the current Subscription AND having a 'Editor' or 'ChiefEditor' status are eligible 'conditions' => '', 'fields' => '', 'order' => '', 'limit' => '', 'offset' => '', 'finderQuery' => '', 'deleteQuery' => '', 'insertQuery' => '' )
  • 好的。然后在find()之前加上$this->Post->recursive=1;
  • 如何解决Column not found?充其量只是限制可用信息。
  • 谢谢,我已经添加了。不幸的是,它没有成功。我将递归级别提高到 6,这也没有什么不同。我怀疑我必须使用连接,下面的@richardathome 似乎证实了这一点。我会试试他的方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-06
相关资源
最近更新 更多