Search code examples
laravel-5eloquentmany-to-manylaravel-5.1detach

Remove relationship between Eloquent records


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;


Solution

  • 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, ...]);