Laravel relationships attach if not already attached
Using syncWithoutDetaching
or sync([arr], false)
looks cleaner in code, but performs 25x slower than attach()
. This is because it checks each id and performs individual database inserts per item.
I'd suggest building upon Paul Spiegel's answer by extending eloquent or creating a new method on your model class.
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.
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
Laravel has built-in method for this - syncWithoutDetaching:
$message->Users()->syncWithoutDetaching($request->get('users'));