Search code examples
mysqllaravellaravel-4many-to-manyeloquent

Implementing a Laravel 4 Pivot Table using Eloquent


I've got the following structure in my database:

-shared_resources table -tags table -shared_resource_tag table

There is a many to many relationship between shared_resources and tags. When I am creating a shared_resource I do the following:

  1. Add the shared_resource to the shared_resources table
  2. Add the tags to the tags table
  3. Add the shared_resource_id and the tag_id to the shared_resource_tag table

I can manage to get through steps 1 and 2 but for some reason I am unable to make any entries to the pivot table. I don't know why. I set up the relationships in my models accordingly:

SharedResource:

class SharedResource extends Eloquent{
    public function tags(){
        return $this->belongsToMany('Tag');
    }
}

Tag:

class Tag extends Eloquent{
    public function sharedResources(){
        return $this->belongsToMany('SharedResource');
    }
}

Then when I am creating the entries I do this:

        $tags = Array();
        $tags = explode(',', Input::get('tags'));
        foreach($tags as $tag){
            $newTag = new Tag;
            $newTag->name = $tag;
            $newTag->save();
        }

        //Pivot table entry
        $resource->tags()->sync($tags);

        $resource->save();

The code above runs into an error:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'shared_resource_id' in 'where clause' (SQL: select `tag_id` from `shared_resource_tag` where `shared_resource_id` is null) 

I'm very confused as to whats going on, I understood that Eloquent made implementing these n:n relationships easy.


Solution

  • The sync() method will need the id's of the tags, and not the string names which you are giving it. You can try something like:

    $tags = Array();
    $tagIds = Array();
    $tags = explode(',', Input::get('tags'));
    foreach($tags as $tag){
        $newTag = new Tag;
        $newTag->name = $tag;
        $newTag->save();
        $tagIds[] = $newTag->id;
    }
    
    //Pivot table entry
    $resource->tags()->sync($tagIds);
    
    $resource->save();
    

    You can find more info here under Using Sync To Attach Many To Many Models