khkassem
3 years ago

morphToMany morphedByMany adding Multiple Pivot data

Posted 3 years ago by khkassem

Hi

I am trying to use polymophed relation with Laravel and Eloquent,

My Databse :

Employee, EmployeeWorksFor, Section, Department

An employee can work for a section and/or a department

An employee can work for a section, move to another section, and return to the first section (there is a date_in and date_out)

The employee Model :

class Employee extends Model {
    protected $table = 'employee';
    public $timestamps = false;
    protected $fillable = [ 
            'name',
            'surname',
            'email',
    ];
    protected $guarded = [ ];

    public function sections() {
        $employee_worksfor = (new EmployeeWorksfor ());
        return $this->morphedByMany ( Section::class, 
                $employee_worksfor->getTable (), $employee_worksfor->getTable () )->withPivot ( 
                $employee_worksfor->getFillable () );
    }
    public function departments() {
        $employee_worksfor = (new EmployeeWorksfor ());
        return $this->morphedByMany ( Department::class, 
                $employee_worksfor->getTable (), $employee_worksfor->getTable () )->withPivot ( 
                $employee_worksfor->getFillable () );
    }
}

The Section Model

class Section extends Model {
    protected $table = 'section';
    public $timestamps = false;
    protected $fillable = [ 
            'name',
            'phone_number'
    ];
    protected $hidden = [ 
    ];
    protected $guarded = [ ];
    
    
    public function employee()
    {
        return $this->morphToMany(Employee::class, EmployeeWorksfor::class);
    }
}

The Department Model

class Department extends Model
{
    protected $table = 'department';
    public $timestamps = false;
    protected $fillable = [
        'name'
        'phone_number'
    ];
    
    protected $guarded = [];

    public function employee()
    {
        return $this->morphToMany(Employee::class, EmployeeWorksfor::class);
    }
}

The EmployeeWorksfor Model, the pivot table

class EmployeeWorksfor extends Model
{
    protected $table = 'employee_worksfor';
    public $timestamps = false;
    protected $fillable = [
        'employee_id',
        'date_from',
        'date_to',
        'is_manager'
    ];
    protected $hidden = [
            'employee_worksfor_id',
            'employee_worksfor_type'
    ];
    protected $guarded = [];
}

My problem is when I try to add data, I want to add or sync pivot data, with the possiblity to have the same employee_id and section_id twice in the worksfor table with just different dates. but the sync function is just saving one line of data

for exemple if i have

employee_id = 1, section_id = 1 and date_from = 12/12/2012

employee_id= 1, section_id = 1 and date_from = 12/12/2016

the sync function is only adding or syncing one line of data.

My controller

class EmployeeController extends Controller {

    private function fill_pivot_data(Array $array){
        $data_to_sync = [];
        foreach ($array as $item){
                
            $pivot_data = isset($item['pivot'])?$item['pivot']:[];
            unset($pivot_data['employee_worksfor_id']);
            $data_to_sync[$item['id']] = $pivot_data;
        }
        return $data_to_sync;
    }

    public function update(Request $request, $id) {
        //
        $employee = Employee::find ( $id );
        
        $data = $request->all ();
        
        $employee->fill ( $data );
        $employee->save ();
        
        // saving worksfor_section
        $employee->sections ()->sync($this->fill_pivot_data($data['sections']));

        return $employee ['id'];
    }
}

the pivot_data array seems to be the problem, if the key of the array is the section key, so it's normal to only have one section saved.

What am i doing wrong?

Note : Before trying to do it with polymorphing, I had worksfor_section and works_fordepartment with hasMany relations and it was woking fine.

Please sign in or create an account to participate in this conversation.