Remove relationship between Eloquent records

Shannon Phillips picture Shannon Phillips · Dec 1, 2015 · Viewed 13.7k times · Source

I've created two classes extending Eloquent (contacts and tags), they have a ManyToMany relationship. I'm trying to create the method for un-tagging a contact, but am unable to find any documentation to tell how to remove the entry in the relation-table without deleting either the tag itself or the contact.

So far, I've tried

$contact = Contact::find($contact_id);
$tag = $contact->tags->where('id', '=', $id);
$tag->delete();

This only deletes the contact. It makes sense that it doesn't work, but I'm not sure what else to try. I don't want to delete the contact or the tag, just the relationship between the two.

I've also now tried:

$tag = Tag::find($id);
$tag->contacts->detach($contact_id);

This gives me the error:

BadMethodCallException in Builder.php line 2071: Call to undefined method Illuminate\Database\Query\Builder::detach()

as well as

$tag = Tag::find($id);
$contact = $tag->contacts->find($contact_id);
$tag->contacts->detach($contact);

This gives me the error:

FatalErrorException in Tag.php line 34: Call to undefined method Illuminate\Database\Eloquent\Collection::detach()

Both the Contacts and Tags classes extend Illuminate\Database\Eloquent\Model;

Answer

andrewtweber picture andrewtweber · Dec 1, 2015

You can use detach for many-to-many relationships

http://laravel.com/docs/5.1/eloquent-relationships#inserting-many-to-many-relationships

You just pass in the ID of the Tag. Take note of the parentheses after "tags"

$contact->tags()->detach($id);

Since it's many-to-many you could do the reverse as well

$tag->contacts()->detach($contact_id);

Similarly, you can use attach to create relationships. Just guessing since you didn't know about detach that you probably could use attach as well. Attach can take a single ID or an array of IDs (plus some more advanced options)

$contact->tags()->attach($id);
$contact->tags()->attach([$id1, $id2, ...]);