Home > Software engineering >  Laravel Eloquent is there a better way to write this query?
Laravel Eloquent is there a better way to write this query?

Time:02-27

I have a typical pivot table structure like this:

Users

id [...]

Locations

id [...]

User_Location

id | user_id | location_id

I need to get the locations the current authorized user has access to, and then I need to get all the users who also have access to all of those locations.

I tried to figure out an "eloquent" way to do this, but I'm not familiar enough with it. This works, but I'm wondering if it's the best way to do it?

    $locations = auth()->user()->locations(); //returns the user_location records
    $locationIds = $locations->pluck('location_id');

    $locationUsers = new UserLocation();
    $userIds = $locationUsers->whereIn('location_id', $locationIds)->groupBy('user_id')->pluck('user_id');
    $users = User::withTrashed()
      ->whereIn('id', $userIds)
      ->get();

    return view('users.index')->with('users', $users);

here's the locations() relationship referenced in the code:

  public function locations()
  {
    return $this->belongsToMany(Location::class, 'user_location')->withPivot('primary');
  }

CodePudding user response:

You must create a new method in the Locations model.

public function users()
{
    return $this->belongsToMany(User::class, 'user_location');
}

Then your query could look like this.

$locations = auth()->user()->locations()->with('users')->get();
$users = $locations->pluck('users');

If you need to get all users withTrashed then you should modify the first line for this.

$locations = auth()->user()->locations()->with(['users' => function ($user) {
    $user->withTrashed();
}])->get();

CodePudding user response:

if the locations has a long lat, it's better to do it one to many, not many to many, because one location is less likely to fit another person. If not, then a good solution @MrEduar

  • Related