我不需要从相关模型中获取数据。 我有模特邮政 我也有模特评论。
每篇博文都有评论。 我在模型之间做了相关的事情:
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->场景是空的。
答案 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