2016-04-14 6 views
10

In meiner Laravel Anwendung habe ich die folgenden Klassen:HasManyThrough mit polymorphen und many-to-many-Beziehungen

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'); 
    } 
} 

Ich kann leicht Benutzer eines Bar Objekt erhalten mit Bar::find(1)->product->users und ich kann auch die Stäbe eines bekommen Benutzer mit User::find(1)->products.

Wie bekomme ich die Benutzer aller Bars, die zu einem bestimmten foo gehören? Das heißt, Foo::find(1)->users sollte alle Benutzer zurückgeben, die die Bars haben, die zu Foo mit ID 1 gehören. Es ist im Grunde hasManyThrough mit polymorphen und viele-zu-viele-Beziehungen.

Antwort

2

versuchen, etwas wie folgt aus:

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

Diese sollte Arbeit für Sie (Code getestet wurde, aber nicht gegen die exakt gleiche Struktur wie Ihr Setup). Die erste Zeile gibt alle Benutzer zurück, die über die Beziehungen tief verschachtelt sind. Die zweite Zeile zieht die Benutzer heraus, flacht sie in ein Array ab und transformiert das Array in eine Sammlung.

+0

Dies scheint Benutzer einzuschließen, die nicht mit dem gegebenen Foo verwandt sind. –

+0

Verwenden Sie eine 'find' Anweisung anstelle einer' get' Anweisung dann: '$ Foo = static :: with (['bars', 'bars. products ',' bars.product.users ']) -> find ($ this-> id); '(angenommen, dein Primärschlüssel ist' id ') –