Search code examples
phplaravellaravel-5.5

sync intermediate table in laravel error: Field doesn't have a default value


I am having trouble with syncing the intermediate table in laravel 5.5.

The post blog data that came from the request is saving...but when sync the tags i get this error:

"SQLSTATE[HY000]: General error: 1364 Field 'TagID' doesn't have a default value (SQL: insert into `blog_post_tag` (`PostID`) values (13))"

Let me explain what i have:

There are 3 tables: blog_posts, blog_tags, blog_post_tag (the intermediate table)

In BlogPost model:

protected $table = 'blog_posts';
protected $primaryKey = 'PostID';

public function tags(){
    return $this->belongsToMany('App\BlogTag', 'blog_post_tag', 'PostID', 'PostID');
}

and BlogTag model:

protected $table = 'blog_tags';
protected $primaryKey = 'TagID';

// a tag can be found in multiple posts
public function posts(){
    return $this->belongsToMany('App\BlogPost', 'blog_post_tag', 'TagID', 'TagID');
}

In BLogController where i have one method that save or update the post:

The savePost method:

// check if update or new
// validate data
// save the post  - until here it`s ok

 // syncronize tags - here comes the problems :)
 if(isset($request->PostID) && $request->PostID != 0) {
     // update post; check if the user delete all the tags for the current post
        if(isset($request->tags)){
            // without the true - which is default - is going to remove all the id`s and put it again
            $post->tags()->sync($request->tags, true);
        }
        else
        {
            // it will remove all the associations (syncs) and is not gonna put anything!
            $post->tags()->sync(array(), true);
        }
    } else {
        // new post; use the sync method to sync the id`s in the blog_post_tag table
        $post->tags()->sync($request->tags, false);
    }

The $request->tags is an array with selected tags(TagsIDs):

<select class="form-control select2-multi" name="tags[]" multiple="multiple">
@foreach($tags as $tag)
    <option value="{{ $tag->TagID }}">{{ $tag->Name }}</option>
@endforeach
</select>

I don't understand what i did wrong? Why is complaining that 'TagID' doesn't have a default value. If i don't send any tags there is no error. The Error is only when update or new post.


Solution

  • You do have problems with customization of the column names of the keys on the table.

    The third argument is the foreign key name of the model on which you are defining the relationship, while the fourth argument is the foreign key name of the model that you are joining to

    Update your BlogPost model

    protected $table = 'blog_posts';
    protected $primaryKey = 'PostID';
    
    public function tags(){
        return $this->belongsToMany('App\BlogTag', 'blog_post_tag', 'PostID', 'TagID');
    }
    

    BlogTag model:

    protected $table = 'blog_tags';
    protected $primaryKey = 'TagID';
    
    // a tag can be found in multiple posts
    public function posts(){
        return $this->belongsToMany('App\BlogPost', 'blog_post_tag', 'TagID', 'PostID');
    }
    

    Laravel Doc

    Let me know if you have any problems with this..