如果尚未附加 Laravel 关系,则附加
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/45356606/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel relationships attach if not already attached
提问by Karim
Is there a quick way of attaching relationships if they're not already attached. I am using this code to update relations of a model;
如果尚未附加关系,是否有一种快速附加关系的方法。我正在使用此代码来更新模型的关系;
if (!empty($request->get('roles')) && is_array($request->get('roles'))) {
$message->Roles()->attach($request->get('roles'));
}
if (!empty($request->get('users')) && is_array($request->get('users'))) {
$message->Users()->attach($request->get('users'));
}
But I am getting this error which I am this error;
但是我收到了这个错误,我就是这个错误;
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-41' for key 'PRIMARY' (SQL: insert into
message_user
(message_id
,user_id
) values (1, 41), (1, 42), (1, 43), (1, 44), (1, 45), (1, 46), (1, 47), (1, 48), (1, 49), (1, 50))
SQLSTATE[23000]: 完整性约束违规: 1062 Duplicate entry '1-41' for key 'PRIMARY' (SQL: insert into
message_user
(message_id
,user_id
) values (1, 41), (1, 42), (1, 43), ( 1, 44), (1, 45), (1, 46), (1, 47), (1, 48), (1, 49), (1, 50))
I want to avoid going through a very long list of array check which users are not already attached and attaching them. Also let me know if this is the only way.
我想避免经过很长的数组检查列表,哪些用户尚未附加并附加它们。也让我知道这是否是唯一的方法。
I am thinking something like;
我在想类似的事情;
$message->Users()->attachIfNotAttached($request->get('users'));
采纳答案by Paul Spiegel
Something like this might work:
像这样的事情可能会奏效:
Get the IDs that are already attached:
获取已附加的 ID:
$attachedIds = $message->Users()->whereIn('id', $request->get('users'))->pluck('id');
Remove the attached IDs from the request array:
从请求数组中删除附加的 ID:
$newIds = array_diff($request->get('users'), $attachedIds);
Attach the new IDs:
附加新 ID:
$message->Users()->attach($newIds);
回答by Karim
Laravel has built-in method for this - syncWithoutDetaching:
Laravel 为此提供了内置方法 - syncWithoutDetaching:
$message->Users()->syncWithoutDetaching($request->get('users'));
回答by Kiee
Using syncWithoutDetaching
or sync([arr], false)
looks cleaner in code, but performs 25x slowerthan attach()
. This is because it checks each id and performs individual database inserts per item.
在代码中使用syncWithoutDetaching
或sync([arr], false)
看起来更简洁,但执行速度比attach()
. 这是因为它检查每个 id 并为每个项目执行单独的数据库插入。
I'd suggest building upon Paul Spiegel's answerby extending eloquent or creating a new method on your model class.
我建议通过扩展 eloquent 或在模型类上创建新方法来构建Paul Spiegel 的答案。
In my use case I have a Feed
class and a Post
class linked by a many to many pivot. I added the following method to my Feed class.
在我的用例中,我有一个Feed
类和一个Post
由多对多支点链接的类。我将以下方法添加到我的 Feed 类中。
public function attachUniquePosts($ids)
{
$existing_ids = $this->posts()->whereIn('posts.id', $ids)->pluck('posts.id');
$this->posts()->attach($ids->diff($existing_ids));
}
- Attaching 20 posts to a feed using
syncWithoutDetaching()
took on average 0.107s - Attaching 20 posts to a feed using
attachUniquePosts()
took on average 0.004s
- 使用将 20 个帖子附加到提要
syncWithoutDetaching()
平均需要 0.107 秒 - 使用将 20 个帖子附加到提要
attachUniquePosts()
平均需要 0.004 秒