Laravel: attach 后需要加载?
Laravel: attach needs to be followed by load?
对于此示例,考虑具有多对多关系的模型 User
和 Comment
。
在用户模型中:
public function comments() {
return $this->belongsToMany(Comment::class);
}
现在,我为用户添加评论:
$user->comments()->attach($comment)
此行将条目添加到数据库数据透视表 table。
但是,如果我现在检查 $user->comments
的值,它仍然是 []
。为了使对象保持最新,我最终不得不做这样的事情:
$user->comments()->attach($comment);
echo $user->comments; // []
$user->load('comments');
echo $user->comments; // [ {id => 1, ...} ]
感觉怪异和多余。有没有更好的方法?
运行 在尝试再次访问评论之前:
$user->refresh();
不确定这是否让您觉得不那么奇怪,但这是从数据库刷新所有用户属性和关系的一种干净方式。
您的做法 ->load()
是最精确的,在某些情况下也是准确的。
您的 echo $user->comments
将检查您是否已经加载评论关系(即:在此请求的前面调用 $user->comments
或使用类似 ->with('comments')
的内容)。我假设您已经在附加评论之前再次调用它只会 return 最初加载的评论(这可以防止对关系的每次调用都执行新查询)。
使用 ->load(..)
将执行查询以刷新评论并为您提供更新的结果。
不过!如果您想避免执行此附加查询,因为您已经拥有所有数据 - 您可以。
您可以手动将新添加的评论附加到评论关系(集合)中:
$user->comments()->attach($comment);
$user->comments->push($comment); // Will manually add the new comment to the existing collection
但是,同样,使用上述方法可能会产生一些意想不到的后果。例如,如果 comments
table 有一些使用 SQL 默认值的列,并且在创建评论时没有明确分配,您将看不到这些。
所以,tldr:除非性能至关重要并且您负担不起额外的查询,否则我会坚持使用您原来的解决方案。
对于此示例,考虑具有多对多关系的模型 User
和 Comment
。
在用户模型中:
public function comments() {
return $this->belongsToMany(Comment::class);
}
现在,我为用户添加评论:
$user->comments()->attach($comment)
此行将条目添加到数据库数据透视表 table。
但是,如果我现在检查 $user->comments
的值,它仍然是 []
。为了使对象保持最新,我最终不得不做这样的事情:
$user->comments()->attach($comment);
echo $user->comments; // []
$user->load('comments');
echo $user->comments; // [ {id => 1, ...} ]
感觉怪异和多余。有没有更好的方法?
运行 在尝试再次访问评论之前:
$user->refresh();
不确定这是否让您觉得不那么奇怪,但这是从数据库刷新所有用户属性和关系的一种干净方式。
您的做法 ->load()
是最精确的,在某些情况下也是准确的。
您的 echo $user->comments
将检查您是否已经加载评论关系(即:在此请求的前面调用 $user->comments
或使用类似 ->with('comments')
的内容)。我假设您已经在附加评论之前再次调用它只会 return 最初加载的评论(这可以防止对关系的每次调用都执行新查询)。
使用 ->load(..)
将执行查询以刷新评论并为您提供更新的结果。
不过!如果您想避免执行此附加查询,因为您已经拥有所有数据 - 您可以。
您可以手动将新添加的评论附加到评论关系(集合)中:
$user->comments()->attach($comment);
$user->comments->push($comment); // Will manually add the new comment to the existing collection
但是,同样,使用上述方法可能会产生一些意想不到的后果。例如,如果 comments
table 有一些使用 SQL 默认值的列,并且在创建评论时没有明确分配,您将看不到这些。
所以,tldr:除非性能至关重要并且您负担不起额外的查询,否则我会坚持使用您原来的解决方案。