0

I have a users table and a services table. I made a many-many pivot table to store which user offers which services. When I try to check or uncheck a service checkbox in my profile blade to modify the user the data is not inserted or removed in the pivot table.

User Model:

public function services(){
        return $this->belongsToMany(Service::class);
    }

Service Model:

public function user(){
        return $this->belongsToMany(User::class);
    }

My code in store function in ProfileController:

$user = Auth::user();
    if(isset($request->services)){
                foreach($request->services as $service_id){
                    $service=Service::find($service_id);
                    $service->user()->syncWithoutDetaching($user->id);
                }
        }

Blade:

<div class="form-group row">
        <label class="col-md-4 col-form-label text-md-right">Type de services</label>

            <label for="peinture">Peinture</label>
            <input type="checkbox" id="peinture" name="services[]" value="1" 
            <?php if (in_array(1, $services->toArray())) echo "checked" ?> >

            <label for="neige">Déneigement</label>
            <input type="checkbox" id="neige" name="services[]" value="2"
            <?php if (in_array(2, $services->toArray())) echo "checked" ?> >

            <label for="gardiennage">Gardiennage</label>
            <input type="checkbox" id="gardiennage" name="services[]" value="3"
            <?php if (in_array(3, $services->toArray())) echo "checked" ?> >

            <label for="entretien">Entretien paysager</label>
            <input type="checkbox" id="entretien" name="services[]" value="4"
            <?php if (in_array(4, $services->toArray())) echo "checked" ?> >
    </div>

If I do dd($request); everything seems in it. No clue what I'm doing wrong, thanks for any help.

3
  • Pls read the tag description before using a tag, they my refer to different concepts, not the one you thought of! Commented Jul 5, 2019 at 21:39
  • syncWithoutDetaching() only adds new IDs but does not remove the existing data. Your code looks okay, just double check if $user has a user model. I doubt the user might not be logged in. Commented Jul 5, 2019 at 22:04
  • @ZeshanKhattak I'm not sure what you mean. I do have a User model. The first block of code is from it. Commented Jul 6, 2019 at 1:44

1 Answer 1

2

you don't need to iterate the services in your controller. just do this:

$user = Auth::user();
$user->services()->sync($request->services);

this will first clean the pivot table, then will attach the new values all at once.

i really encourage you not to use $request values without validating them. in this case run this before start syncing the pivot table:

$this->validate($request, [
    'services' => 'required|array',
    'services.*' => 'exists:services,id',
]);
Sign up to request clarification or add additional context in comments.

2 Comments

I added your code and now everything is working thanks a lot! To be fair my validation is a complete mess right now. As for no need to iterate you mean the foreach is useless?
yes exactly. the sync method generate only one sql query (insert into pivot values (...), (...), (...) ...) while foreach generates an individual query for each service_id @VincentDesrosiers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.