Laravel Eloquent - Attach vs Sync

98

attach()sync()在Laravel 4的Eloquent ORM中有何区别?我尝试寻找答案,但未能找到。

4个回答

177

attach():

  • 在使用多对多关系时,插入相关模型
  • 不需要数组参数

示例:

$user = User::find(1);
$user->roles()->attach(1);

sync():

sync() 方法与 attach() 方法类似,用于关联模型。然而,其主要区别在于:

  • sync() 接受一个 ID 数组来放置在中间表上的 ID
  • 其次,最重要的是,如果模型不存在于数组中,sync 方法将从中间表删除数据,并仅将新项目插入到中间表。

例如:

user_role

id  user_id role_id
1    12       1
2    12       5
3    12       2
$user = User::find(12);
$user->roles()->sync(array(1, 2, 3));

上述操作将删除:

id  user_id role_id
2    12       5

并向表中插入role_id 3

user_role表

id  user_id role_id
1    12       1
3    12       2
4    12       3


20
谢谢!那么理论上,先使用 $user()->roles()->detach($oldIDs) 然后跟着使用 $user()->roles()->attach($newIDs) 和使用 $user()->roles()->sync($newIDs) 是相同的,对吗? - Kousha
30
sync()方法有第二个参数,默认为true。如果你传递false,则不会删除不匹配的内容。请参考此链接:http://laravel.com/api/4.2/Illuminate/Database/Eloquent/Relations/MorphToMany.html#method_sync - Musa Haidari
1
@Deena 实际上,数据透视表不需要任何ID - 因此您不会得到任何ID :) 但是,您可以通过重用模型对象变量来获取相关的ID。 - Seiji Manoan
当数据透视表不仅有2列(用户ID,角色ID)时怎么办?我想要添加一个值到数据透视表的第3列,该如何添加数据到该列? - Henry Bui
3
小提示:attach() 方法接受 ID 数组或单个值作为输入。detach() 方法也是如此。 - Maik Lowrey
显示剩余3条评论

63

更简单的说:

attach函数只会向Pivot表中添加记录。

sync函数则用新记录替换当前记录。这非常适合用来更新模型。

例子:

假设你创建了一个帖子(Post),它有多个标签(Tag)与之关联,这些标签的ID是[1,2,3]

用户可以更新帖子及其标签。

用户将发送新的标签ID [3,4,5] 给你。

如果使用sync函数,帖子的新标签将仅为[3,4,5]

如果使用attach函数,则帖子的新标签将为[1,2,3,4,5]


我的问题与此类似。我可以使用您的答案来解决它,谢谢。https://dev59.com/kGAg5IYBdhLWcg3wG30K#36573783 - saber tabatabaee yazdi

8

已发布的答案没有提到 syncWithoutDetaching,这里是我的简单解释。

如果你想要:

  • 将模型添加到关系中,允许重复,请使用 attach()
  • 将模型添加到关系中,忽略重复,请使用 syncWithoutDetaching()
  • 将关系设置为确切的模型,请使用 sync()

示例:

调用:

$user->articles()->attach(1);
$user->articles()->attach(2);
$user->articles()->attach(1);

echo $user->articles;

将返回文章:1,2,1

调用:

$user->articles()->syncWithoutDetaching([1]);
$user->articles()->syncWithoutDetaching([2]);
$user->articles()->syncWithoutDetaching([1]);

echo $user->articles;

将返回文章:1、2

调用:

$user->articles()->sync([1]);
$user->articles()->sync([2, 3]);
$user->articles()->sync([3, 4]);

echo $user->articles;

将返回文章:3、4


1
你还可以使用同步方法的其他参数:
$user->roles()->sync([1,2,3], true); 

"True"会分离,而false会附加。例如,如果您已经附加了角色1、2、3、4和5,然后您进行编辑并移除5,使用"true"进行同步将会移除5,而使用"false"进行同步将会同步包括已经在数据库中的5在内的新返回值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接