如何在Yii中禁用从相关模型获取数据

时间:2012-12-26 10:29:56

标签: activerecord yii

我不需要从相关模型中获取数据。 我有模特邮政 我也有模特评论。

每篇博文都有评论。 我在模型之间做了相关的事情:

class Post
    public function relations()
    {
        return array(
            'comments' => array(self::HAS_MANY, 'Comment', 'post_id')
        );
    }

    public function scopes()
    {
        return array(
            'orderDesc'=>array(
                'order' => 'post_id DESC',
            ),
        );

    }

    public function findAllPosts()
    {
        return $this->orderDesc()->findAll();
    }

如果我从db发帖,我需要评论 - 没问题。

Post::model()->findByPk()

但如果我收到所有帖子 - 我不需要评论

Post::model()->findAllPosts()

但是我收到了评论的帖子。我认为 - 这对数据库来说并不好 - 使用额外的连接,这对我如何禁用从相关模型中获取数据很有意思。

我试过通过场景和改变方法关系中的行为来做到这一点,但是在方法关系中我总是得到 - $ this->场景是空的。

1 个答案:

答案 0 :(得分:3)

在Yii中,定义的关系默认加载延迟加载。 这意味着只有在代码中调用相关模型时,Yii才会获取相关模型。

所以,如果你这样做

Post::model()->findAll();

不会加载相关模型(即:注释)。但如果你打电话

Post::model()->findAll();
CVarDumper::dump($posts[0]->comments);

然后将执行第二个DB请求以获取相关注释。这就是代码显示注释的原因。

如果您知道您将需要相关模型,那么最佳解决方案是使用预先加载:它包括在加载初始模型的同一请求中加载相关模型。为此,您需要在代码中指定with方法。

示例:

Post::model()->with('comments')->findAll();

此方法with也可以放在模型中的默认范围内或默认范围内。如果它在默认范围内,那么每次加载模型时,他的相关模型都将加载到同一个请求中。

最后一点:

当您使用预先加载时,会执行一个请求来获取相关模型,但这种技术对于每个关系都不是完美的。

例如,如果您有post,并且您想要加载author个人资料,因为只有一个author,请求会很快,只返回一行,所以渴望加载是好的。

但是你要加载comments。由于它只执行一个请求,因此您将拥有包含大量类似信息的几行(所有关于post的信息)。在这种情况下,纯粹的热切加载并不是最好的解决方案。 处理这些关系的最佳方法是在关系数组中指定params together为false。 如果您这样做,则会执行2个请求:第一个用于提取post,第二个用于提取相关的comments

示例:

Post::model()->with('comments' => array('together' => false))->findAll();

来源:Yii Guide