Search code examples
phplaraveleloquentone-to-manylaravel-5.3

Laravel One-To-Many insertion on a Pivot table


I am using Laravel 5.3 ad having issues on saving through the hasMany relationship.

I have tables employee and activity which has One-to-Many Relation i.e Each employee will perform many activities.

When I am adding activities against employee using associate() it send me an error:

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

Below are the DB structure and code:

Database structure:

employee (1st table)
– employee_id
– employee_name
- created_at
- updated_at

activity (2nd table)
– activity_id
– activity_name
- created_at
- updated_at

employee_activity (pivot table)
– employee_activity_employee_id
– employee_activity_activity_id

Model Class Employee:

class Employee extends Model
{
    protected $table = 'employee';
    protected $primaryKey = 'employee_id';

    public function activity() {
        return $this->hasMany('App\Models\Activity', 'employee_activity', 'employee_activity_employee_id', 'employee_id');
    }
}

Model Class Activity:

class Activity extends Model
{
    protected $table = 'activity';
    protected $primaryKey = 'activity_id';

    public function employee() {
        return $this->belongsTo('App\Models\Employee', 'employee_activity', 'employee_activity_activity_id' ,'activity_id');
    }
}

Controller:

public function EmployeeActivityAssociation()
{
    $employee_id = Input::get('employee_id');
    $activity_ids = Input::get('activity_id'); // This is an array of activities
    $employee = Employee::find($employee_id);
    if (!empty($employee)) {
         //Adding activity under the employee
        foreach ($activity_ids as $id) {
            $activity = Activity::find($id);
            $employee->activity()->associate($activity);
            $employee->save();
        }
        return 'Activities asscoiated to employee';
    }   
    else {
        return 'Employee not found';
    }
}

Do I have my relationship defined incorrectly here?


Solution

  • Your relation is not defined correctly. By seeing your table structure it should be many-to-many relationship.

    Model Class Employee:

    public function activity() {
        return $this->belongsToMany('App\Models\Activity', 'employee_activity', 'employee_activity_employee_id', 'employee_id');
    }
    

    Model Class Activity:

    public function employee() {
        return $this->belongsToMany('App\Models\Employee', 'employee_activity', 'employee_activity_activity_id' ,'activity_id');
    }
    

    SO your controller should be as:

    public function EmployeeActivityAssociation()
    {
        $employee_id = Input::get('employee_id');
        $activity_ids = Input::get('activity_id'); // This is an array of activities
        $employee = Employee::find($employee_id);
        if (!empty($employee)) {
            $employee->activity()->attach($activity_ids);
          return 'Activities asscoiated to employee';
        }   
        else {
            return 'Employee not found';
        }
    }
    

    If you want to stick to one-to-many relation then you have to change your table schemas as:

    Remove table employee_activity table and add column employee_id in activity table then define relation according to one-to-many.