Search code examples
laraveleloquentilluminate

Laravel | Check that user belongs to all relationships BelongsToMany


I am trying to create a policy for updating a user to ensure that either the person updating or the user being updated belongs to a place.

I have the current database structure for the users

| id | first_name | last_name | email | password | created_at | updated_at |

and this is the places

| id | name | description | created_at | updated_at | 

I then have a pivot table which is

| user_id | place_id |

Everything links up correctly and I can pass and associate data into each models.

What I am trying to achieve is that when I send in a request according to the JSON API spec which looks like the following:

{
  "type": "users",
  "attributes": {
    ...
  },
  "relationships": {
     "places": {
       "data": [
         {
           "type": "places",
           "id": "1"
         },
         {
           "type": "places",
           "id": "2"
         }   
       ]
     }
  }
}

Inside of the updated policy, I want to check that either the authenticated user or the user being updated belongs to that place.

I have a method on the User model which is the following:

public function belongsToPlaces($placeIds) 
{
    return $this->places()->whereIn('id', $placeIds)->count() === count($placeIds);
}

This seems to work but it really doesn't feel very secure as realistically I should check each of the IDs. I'm just wondering if there is a built-in method to do this?


Solution

  • I would do a diff on the placeIds you already have with the one on the user. It will return all place ids there is not in the request, if it's not present on the users places. So check if the diff is empty, then everything is fine, otherwise the id's are invalid.

    public function belongsToPlaces($placeIds) 
    {
        return collect($placeIds)->diff($this->places()->pluck('id'))->isEmpty();
    }