Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ravasaurio's avatar

How does the 'associate' method work behind the scenes?

I am using the spatie/laravel-permission in my project. I am hiding some routes behind their middleware to avoid unauthorized users to use them. But I am having a problem. When I do this:

$profile->user()->associate($user);

as part of the process of creating a user, I get the "You do not have access to do that." alert.

The user gets created, the profile gets created but they do not get associated to each other. If I manually assign the corresponding IDs it works fine.

I am using the associate() method in other part of the application intended to be used by another role and it works fine, so my guess is that the associate()method is trying to do something I don't know and somewhere it's getting rejected by the role/permission middleware.

What could it be?

0 likes
7 replies
bashy's avatar

Have you got any permissions for saving users in role_has_permissions?

1 like
ravasaurio's avatar

I see I provided very little info. Sorry about that.

These are the routes involved in the process:

  Route::group([
    'middleware'  =>  'role:entity',
  ], function (){

    Route::get('create_commerce', 'EntityController@createCommerce')->name('create_commerce');
    Route::post('store_commerce', 'EntityController@storeCommerce')->name('store_commerce');

  });

EntityController@storeCommerce:

public function storeCommerce(StoreCommerceRequest $request)
  {
    $this->entityRepository->createCommerce($request->only(
        'first_name',
        'last_name',
        'email',
        'timezone',
        'position',
        'assigned_test',
        'commerce',
        'phone',
        'web',
        'fuc',
        'dba',
        'address',
        'postal_code',
        'city',
        'province',
        'country'

    ));

    return redirect()->route('admin.entity.users')->withFlashSuccess(__('alerts.backend.users.created'));
  }

StoreCommerceRequest:

public function authorize()
    {
        return $this->user()->can('create commerces');
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
            'first_name'     => 'required|max:191',
            'last_name'  => 'required|max:191',
            'email'    => ['required', 'email', 'max:191', Rule::unique('users')],
            'position'      =>  'required|alpha',
            'assigned_test' =>  'nullable|numeric|exists:tests,id',
            'commerce'      =>  'required',
            'phone'         =>  'required',
            'web'           =>  'nullable',
            'fuc'           =>  ['required', Rule::unique('commerces')],
            'dba'           =>  'required',
            'address'       =>  'required',
            'postal_code'   =>  'required',
            'city'          =>  'required',
            'province'      =>  'required',
            'country'       =>  'required',
        ];
    }

And finally, EntityRepository->createCommerce:

public function createCommerce(array $data)
    {
      return DB::transaction(function () use ($data) {
        //creates the user
        $user = User::create([
            'first_name' => $data['first_name'],
            'last_name' => $data['last_name'],
            'email' => $data['email'],
            'timezone' => $data['timezone'],
            'password' => Hash::make(str_random(16)),
            'active' => 1,
            'confirmation_code' => md5(uniqid(mt_rand(), true)),
            'confirmed' => 0,
        ]);

        // Add commerce role
        $user->assignRole('commerce');

        $commerce = Commerce::create([
          'position'      =>  $data['position'],
          'assigned_test' =>  $data['assigned_test'],
          'commerce'      =>  $data['commerce'],
          'phone'         =>  $data['phone'],
          'web'           =>  $data['web'],
          'fuc'           =>  $data['fuc'],
          'dba'           =>  $data['dba'],
          'address'       =>  $data['address'],
          'postal_code'   =>  $data['postal_code'],
          'city'          =>  $data['city'],
          'province'      =>  $data['province'],
          'country'       =>  $data['country'],
        ]);

        //assign new commerce to corresponding entity and user
        $entity = Entity::find(Auth::user()->entity->first()->id);

        $commerce->user()->associate($user);
        $commerce->entity()->associate($entity);

        $licenses = $entity->remaining_licenses;

        $entity->remaining_licenses = $licenses-1;
        //set user type to 'commerce'
        $user->type='commerce';
        //persist data
        $entity->save();
        $commerce->save();
        $user->save();

        event(new UserCreated($user));
        return $user;
      });
    }

The user doing all this stuff has both the entity role and the create commerces permission. Can you see anything here that could require another permission?

ravasaurio's avatar
ravasaurio
OP
Best Answer
Level 2

I found the problem and now I feel very dumb. After the user is created, on EntityController I was redirecting to the wrong route, one protected by the role middleware for admins only

public function storeCommerce(StoreCommerceRequest $request)
  {
    $this->entityRepository->createCommerce($request->only(
//etc

    ));

    return redirect()->route('admin.entity.users')->withFlashSuccess(__('alerts.backend.users.created'));
  }

And to feel even more dumb, I didn't even posted that line on my issue here...

It works now, but still I don't know why everything would work except the associate() method. any Ideas?

shez1983's avatar

you could always go to the associate() method in laravel framework and see what it does and whether it has permission checking etc

bashy's avatar

So if you dd($this->user()->can('create commerces')); in the authorize method it's true?

1 like
ravasaurio's avatar

dd($this->user()->can('create commerces'));returns true.

bashy's avatar

@ravasaurio Sorry I think I left this thread open and didn't see your answer :P

1 like

Please or to participate in this conversation.