HasManyThrough с полиморфными и многими-ко-многим отношениями

В моем приложении Laravel у меня есть следующие классы:

class Product extends Model
{
    public function extended()
    {
        return $this->morphTo();
    }

    public function users {
        return $this->belongsToMany('App\User', 'products_users', 'product_id');
    }
}

class Foo extends Model 
{
    public function product()
    {
        return $this->morphOne('App\Product', 'extended');
    }
    public function bars()
    {
        return $this->hasMany('App\Bar');
    }
}

class Bar extends Model 
{
    public function product()
    {
        return $this->morphOne('App\Product', 'extended');
    }

    public function foo()
    {
        return $this->belongsTo('App\Foo');
    }
}

class User extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Product', 'products_users', 'user_id');
    }
}

Я могу легко получить пользователей из объекта bar с помощью Bar::find(1)->product->users, и я также могу получить бары пользователя с User::find(1)->products.

Как я могу получить пользователей всех баров, принадлежащих к определенному foo? То есть Foo::find(1)->users должен возвращать всех пользователей, у которых есть бары, принадлежащие Foo с идентификатором 1. В основном hasManyThrough с полиморфными и многими-ко-многим отношениями.

Ответ 1

Попробуйте что-то вроде этого:

public function users()
    {
        $Foo = static::with(['bars', 'bars.products', 'bars.product.users'])->get();
        return collect(array_flatten(array_pluck($Foo, 'bars.*.product.users')));
    }

Этот должен работать для вас (код был протестирован, но не против той же структуры, что и ваша настройка). Первая строка вернет всех пользователей, глубоко вложенных в отношения. Вторая строка вытащит пользователей, сгладит их в массив, а затем преобразует массив в коллекцию.