Reputation: 1095
A branch may have zero(*) or only one holiday plan. A holiday plan may be "linked" (attached) to zero or many branches.
(*) this is very important: it is a Foreign Key
which may be null
Here is my Branch
Model:
class Branch extends Model
{
protected $table = 'branch';
protected $fillable = ['name', 'holiday_plan_id'];
public $timestamps = false;
public function holidayPlan()
{
return $this->hasOne('App\HolidayPlan', 'id', 'holiday_plan_id');
}
}
And here is my HolidayPlan
Model:
class HolidayPlan extends Model
{
protected $table = 'holiday_plan';
protected $fillable = ['name'];
public $timestamps = false;
public function branches()
{
return $this->hasMany('App\Branch', 'holiday_plan_id', 'id');
}
}
Now I want to link/unlink a holiday plan to different branches
$branches = Branch::all();
$plan = HolidayPlan::find(1);
@foreach($branches as $branch)
<label>
<input type="checkbox" name="branch[]"
value="{{ $branch->id }}"{{ ($branch->holiday_plan_id == $plan->id) ? ' checked' : '' }}>
{{ $branch->name }}
</label>
@endforeach
public function linkBranches($planId, Request $request) // post
{
$plan = HolidayPlan::where('id', $planId)->first();
$branches = Branch::findMany($request->input('branch'));
//
$this->solution1($plan, $branches); // see next
//
return redirect()->back();
}
private function solution1(HolidayPlan $plan, $branches)
{
$plan->branches()->sync($branches); // Not working because this function is for Many-to-Many relations
}
private function solution2(HolidayPlan $plan, $branches)
{
$plan->branches()->delete(); // This will delete my branches, which is not what I want to do, of course
$plan->branches()->saveMany($branches);
}
private function solution3(HolidayPlan $plan, $branches)
{
foreach($plan->branches as $branch) {
$branch->holiday_plan_id = null;
$branch->save();
}
$plan->branches()->saveMany($branches); // Not working; I don't know why: strange behavior. Maybe because of locks; I'm not sure. One time it detaches all branches, and only next time it attaches them again.
}
Actually, a raw SQL would be:
UPDATE branch SET holiday_plan_id = NULL WHERE holiday_plan_id = 1;
UPDATE branch SET holiday_plan_id = 1 WHERE branch.id IN (2, 5, 7)/* for example */;
But how to do this using Eloquent functions and relations (without raw sql)?
I've edited my Branch
model relationship, however solution3
still doesn't work (when I try to add an already existing holiday_plan_id
, it doesn't add it = it becomes null):
public function holidayPlan()
{
return $this->belongsTo('App\HolidayPlan', 'holiday_plan_id');
}
Upvotes: 3
Views: 2434
Reputation: 1095
Temporary Solution:
public function solution4(HolidayPlan $plan, $inputBranches)
{
$oldLinks = $plan->branches;
$plan->branches()->saveMany($inputBranches);
foreach ($oldLinks as $oldLink) {
if (! $inputBranches->contains($oldLink)) {
$oldLink->holiday_plan_id = null;
$oldLink->save();
}
}
}
Upvotes: 3