Search code examples
laraveleloquentpivotrelationshipeloquent-relationship

laravel many to many relationship not store in pivot table


I have two tables developer table and skill table which are linked with many to many relationship developer_skill table. I want to store developer_id and skill_id is in pivot table.

but when developer add their skills and submit it return error.

on developer table data add but in pivot table data not added. error

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'developer_id' cannot be null (SQL: insert into `developer_skill` (`developer_id`, `skill_id`) values (, 5))

developer controller to store data

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Developer; 
use App\Skill as skill;

class developerController extends Controller
{
    public function __construct(Developer $Developer, skill $skill)
    {
        $this->Developer = $Developer;
        $this->skill = $skill;
    }

     public function store(Request $request)
      {
       $skills = implode(',', $request->user_skills);
    
          $data = array(
                'name' => $request->name,
                'skills' => $skills,
            );
    
            if ($this->Developer->create($data)) {
                $syncTagData = array();
                if (!empty($request->user_skills)) {
                    $syncTagData = $request->user_skills;
                }
    
                $this->Developer->user_skills()->sync($syncTagData);
            }
}
}

developer_skill

developer_id
skill_id

skill model

public function users()
{
    return $this->belongsToMany(Developer::class);
}

developer model

public function user_skills()
    {
        return $this->belongsToMany('App\Skill');

}

Solution

  • Your problem is here:

    if ($this->Developer->create($data)) {
        $syncTagData = array();
        if (!empty($request->user_skills)) {
            $syncTagData = $request->user_skills;
        }
    
        $this->Developer->user_skills()->sync($syncTagData);
    }
    

    $this->Developer is already and instance of Developer so when you call create() the query it builds isn't what you might expect.

    You have two options:

    Use the model Facade (my preference):

    if ($developer = Developer::create($data)) {
        $syncTagData = array();
        if (!empty($request->user_skills)) {
            $syncTagData = $request->user_skills;
        }
    
        $developer->user_skills()->sync($syncTagData);
    }
    

    Using the above, you should be able to remove your constructor as it's not needed.

    Or set the properties on $this->developer and save:

    $this->Developer->name = $data['name'];
    $this->Developer->skills = $data['skills'];
    if ($this->Developer->save()) {
        $syncTagData = array();
        if (!empty($request->user_skills)) {
            $syncTagData = $request->user_skills;
        }
    
        $developer->user_skills()->sync($syncTagData);
    }
    

    Also, be careful with your user_skills relationship name. The convention is camelCase so you might benefit from changing it to userSkills otherwise you may find odd things happening when Laravel does its magic under the hood.