【问题标题】:Finding records via conditions in HABTM通过 HABTM 中的条件查找记录
【发布时间】:2010-11-27 00:39:15
【问题描述】:

我正在尝试在与某个类别相关联的类别中查找帖子。现在,我有这个:

$this->set('posts', $this->Category->Post->find('all', array('conditions' => array('Category.uri' => $uri))));

但这似乎不起作用。显示错误:

Warning (512): SQL Error: 1054: Unknown column 'Category.uri' in 'where clause' [CORE/cake/libs/model/datasources/dbo_source.php, line 684]

..<snipped>...

Query: SELECT `Post`.`id`, `Post`.`title`, `Post`.`uri`, `Post`.`body`, `Post`.`created`, `Post`.`modified` FROM `posts` AS `Post` WHERE `Category`.`uri` = 'holidays'.

我了解到,当您在模型之间使用 HABTM 时,您应该能够像这样检索它。但是,显示的 SQL 并未加入类别表。

// Category Model
class Category extends AppModel {
    var $name = 'Category';
    var $hasAndBelongsToMany = array(
        'Post' => array(
            'className' => 'Post'
        )
    );
}

// Post Model
class Post extends AppModel {
    var $name = 'Post';
    var $hasAndBelongsToMany = array(
        'Category' => array(
            'className' => 'Category'
        )
    );
}

【问题讨论】:

    标签: cakephp has-and-belongs-to-many


    【解决方案1】:

    当你有 HABTM 时,我已经读过 在模型之间,您应该能够 像这样检索它。

    我不知道你在哪里看到的,但你的来源是错误的。 Cake's documentation of HABTM associations 处理的场景几乎与您的相同,以及实现您所追求的结果所需的步骤。

    My answer to another question about HABTM 可能有助于了解 Cake 的 ORM 如何在幕后工作。

    【讨论】:

    • 关于 CakePHP ORM 内部结构的好信息,但看不出有什么帮助。
    • 它有助于解释为什么不能通过 Categories 的属性来限制对 Posts 的查询——因为在幕后,Cake 永远不会在 categories 和 @987654325 上执行 JOIN @表。这是一次“教钓鱼”而不是“授鱼”的尝试。 :-)
    • 好吧,我是在阅读了 teknoid 的一篇关于 HABTM 的博文后才知道的。谢谢。
    【解决方案2】:

    这似乎奏效了。有没有更有效的方法来做到这一点?

    $options['joins'] = array(
        array('table' => 'categories_posts',
            'alias' => 'CategoriesPosts',
            'type' => 'LEFT',
            'conditions' => array(
                'Category.id = CategoriesPosts.category_id'
            )
        ),
        array('table' => 'posts',
            'alias' => 'Post',
            'type' => 'LEFT',
            'conditions' => array(
                'CategoriesPosts.post_id = Post.id',
            )
        )
    );
    $options['conditions'] = array(
        'Category.uri' => $uri
    );
    $options['fields'] = array(
        'DISTINCT(Category.uri), Post.*, Category.*'
    );
    $this->set('posts', $this->Category->find('all', $options));
    

    【讨论】:

    • 以这种方式解决您的问题并没有什么大问题。我要给出的唯一警告是您正在破坏 Cake 的 ORM 抽象。您可以使用 Model::bindModel 达到同样的效果,不需要您的模型完全了解您的数据源是如何工作的。
    • 这肯定不是最简单的方法
    【解决方案3】:

    这是更高效的代码:

    $this->set('posts', $this->Category->find(
        'first',
        array(
            'conditions' => array(
                'Category.uri' => $uri
            ),
            'contain' => array('Post')
        )
    ));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 2012-10-15
      相关资源
      最近更新 更多