当我在模型中声明关系时,例如:
class Post extends Model
{
public function comments()
{
return $this->hasMany(Comment::class);
}
}
当我检索Post实例或我写的那一刻
时,是否从数据库中检索了注释$post->comments;
答案 0 :(得分:1)
答案很简单:
$post->comments() returns the relationship object
$post->comments returns the result of the relationship
所以当你执行$post->comments
这意味着获取关系并执行查询时,就会返回关系数据库结果。
答案 1 :(得分:1)
当你提出要求时会检索它们,即$post->comments
。如果您想加载它们,可以写Post::with('comments')->get()
。查看documentation。它解释了急切的加载和N + 1问题。
来自文档:
当访问Eloquent关系作为属性时,关系数据是"延迟加载"。这意味着在您首次访问该属性之前,实际上不会加载关系数据。然而,Eloquent可以“急切地”加载"查询父模型时的关系。急切加载缓解了N + 1查询问题。
答案 2 :(得分:1)
到目前为止,答案已经解决了这个问题,但不是很清楚,所以请允许我帮忙。要直截了当地回答您的问题,创建Post
实例 也会加载关联的comments
。
原因如下:
当您定义一个Eloquent关系时,您基本上会附加一个全新的查询'你的对象的方法,所以除非你打电话,否则它不会被实际执行。
作为一个简单示例,我们有Car
:
class Car {
public $color;
public function __construct() {
$this->color = 'blue';
}
public function makeRed() {
$this->color = 'red';
return $this;
}
}
在此示例中,实例化的Car
只有一个属性color
。这辆车将为蓝色,除非您调用makeRed()
方法并进行更改。它不同时计算两个选项,期望您可能决定更改它的颜色。
因此,为了将其与Eloquent关系相关联,comments
方法返回一个关系对象,但前提是在Post
对象上调用该方法。在此之前,您的Post对象不会自动调用它自己的方法。基本上,不要担心物体会因大量方法而变大,因为这些方法只有在实际调用时才会显着影响物体尺寸。
如果您希望comments
立即加载Post
,则急切加载初始查询将允许此操作:
$post = Post::with('comments')->findOrFail('post_id');
否则,以下内容将为您提供给定帖子的评论:
$post = Post::findOrFail('post_id');
$post->comments;
有关详细信息,请参阅Eager Loading上的Laravel文档。
希望这有帮助!