5

I know, how to use Laravel policies and everything works, but I am stuck with create(...) method.

My app is a training diary for ski racers. Each racer can manage (view, add, edit..) his own diary. Each trainer can manage his own diary, diary of all racers but not other trainers. I use native Laravel Policies and it works great during *update(...) and delete(...) method, but not create(...).

TrainingRecordPolicy.php:

public function update(User $user, TrainingRecord $record)
{
    if ($user->id == $record->user->id) {
        return true;
    }
    if ($user->isTrainer() && $record->user->isRacer()) {
        return true;
    }
    return false;
}

I'm using it in controllers like $this->authorize('update', $record). But if I want to check, if user can create new record into others user diary, I have no idea how to deal with it.

This doesn't work $this->authorize('create', TrainingRecord::class, $diaryOwner) and if I use $this->authorize('createDiaryRecord', $diaryOwner) it calls method inside UserPolicy.

How do I send $diaryOwner as extra parameter to create() method within the policy?

Note: $diaryOwner is retrieved from the route parameter user in route with signature /diary/{user}

Kyslik
  • 8,217
  • 5
  • 54
  • 87
Arxeiss
  • 976
  • 16
  • 34
  • How do you get `$diaryOwner`? – Kyslik May 08 '18 at 15:29
  • From route parameter: `/diary/{user}/new-record`. There is no detail (view) of TrainingRecord. There is only table for whole season, where all records are listed in something like calendar agenda. – Arxeiss May 08 '18 at 15:46
  • So in the example `$this->authorize('create', ..., $diaryOwner)` `$diaryOwner` is instance of User or just `id`? What is the relationship between User model and Diary model? Add it to the OP. – Kyslik May 08 '18 at 15:50
  • There is no model `Diary`. There are 2 models `TrainingRecord` and `User`. User can have more records. In route `/diary/{user}` you can see all `TrainingRecords` of user in something like calendar agenda. You can think about it as calendar. You have calendar, your trainer has calendar. He can write into your own one. But you cannot write into his – Arxeiss May 08 '18 at 16:13

1 Answers1

6

You can access the $diaryOwner within the policy using request() helper.

public function create(User $user) 
{
    $diaryOwner = request()->user; // because route is defined as /diary/{user}
}

There may be a problem because:

When using dynamic properties, Laravel will first look for the parameter's value in the request payload. If it is not present, Laravel will search for the field in the route parameters.

So instead of using request()->user use request()->route()->parameter('user').

Also if you are using \Illuminate\Routing\Middleware\SubstituteBindings::class you will get User instance.

Kyslik
  • 8,217
  • 5
  • 54
  • 87