首页 > 解决方案 > Eloquent relations from multiple joined tables

问题描述

Let's say we have a table users and we are left joining multiple tables to it.

        $users = User::query()
            ->select('users.id', 'bananas.id as banana_id', 'dogs.id as dog_id')
            ->leftJoin('bananas', 'banana.user_id', '=', 'users.id')
            ->unionAll($usersWithDogs) // a similar query with a left join on `dogs`
            ->orderByDesc('users.created_at')
            ->paginate(...);

We end up with a collection of User models with attributes id, dog_id, banana_id.

Now imagine we want to eager load these, but the eloquent relations are based on the one to many relationships, $user->dogs, $user->bananas.

Trying to find a solution that will do all the following:

a) not break pagination
b) allow ordering on the user table
c) allow eager loading
d) use clean code
e) end up with a collection of users

Brainstorming so far has led to the following options:

  1. A union of bananas and dogs, eager load the user relation, then invert the collection (messy code)
  2. Dynamic relationships created on User, possibly with a macro on \Illuminate\Database\Eloquent\Builder. Maybe by leveraging Model::resolveRelationUsing()
  3. Manual eager loading with a union select with a left join to each table in each arm of the union, then a whereIn() to get the related records
  4. Restructure the relations so that there is a polymorphic many to many relationship between users and other entities e.g.
    user_id | model_type        | model_id
    1       | App\Models\Banana | 2
    1       | App\Models\Dog    | 5

Maybe I'm missing something obvious...?

标签: laraveleloquent

解决方案


推荐阅读