deep
deep

Reputation: 57

Laravel - Save additional column value to pivot table

I want to save additional boolean value to to intermediate table in pivot table. I have models with belongstoMany relation. I want to save pivot table city_school like this.

But the same value of is_open saved for all schools. Only related is_open value must be stored for each school_id.

city_id | school_id | is_open
   1          1         0
   1          2         1

My Models:

City.php

public function schools()
{
    return $this->belongsToMany(School::class)->withPivot('is_open')->withTimestamps();
}

School.php

public function cities()
{
    return $this->belongsToMany(City::class)->withPivot('is_open')->withTimestamps();
}

View.blade.php

<div>LA<input type="hidden" name="school[]" value="1">
<input type="checkbox" name="is_open[1]">Open

<div>SF<input type="hidden" name="school[]" value="2">
<input type="checkbox" name="is_open[2]">Open

Controller

$school = $request['school'];
$data->schools()->attach($school, ['is_open' => $request->has('is_open')?1:0]);

Upvotes: 2

Views: 573

Answers (1)

Tim Lewis
Tim Lewis

Reputation: 29288

Since $schools is an array, you'd have to loop and construct what is known as a "syncArray":

$syncArray = [];
foreach ($request->input('schools') as $schoolId) {
  $syncArray[$schoolId] = [
    'is_open' => $request->has("is_open.{$schoolId}") ? 1 : 0
  ];
}

In the above example, $syncArray would contain an array of $schoolIds, mapped to an array of "additional attributes", in this case is_open:

[1 => ["is_open" => 1], 2 => ["is_open" => 0]]

Then, you'd simply call:

$data->schools()->syncWithoutDetaching($syncArray);

And all the records in your pivot table would be updated to reflect what you've passed. Normally, you'd call sync(), but that removes anything not within $syncArray(), and since this is only updating an attribute, you wouldn't want that.

Upvotes: 1

Related Questions