2014-12-14 16 views
11

Ich habe drei Tabellen garages, cars, securities.Hat einen durch Laravel Eloquent

Die Wertpapiere sind diejenigen, die ein Auto sicher halten, Sie können mehr als ein Wertpapier haben, aber ein einzelnes Wertpapier kann nur ein Auto sicher halten. Die Garage ist, wo das Auto ist und die Wertpapiere sind auch.

Ich möchte alle Wertpapiere auflisten und kenne den Namen der Werkstatt, die er ist. Das Problem ist, dass securities hat keine Spalte mit der ID der Garage, nur die ID des Autos, das er sicher ist, aber Auto hat die ID der Garage.

Laravel Eloquent hat eine Methode namens hasManyThrough, aber securities hat nur eine garage bis cars. Hier

ist die Tabellen:

Garagen Tabelle:

----------------------------------- 
|garage_id|garage_name|garage_size| 
----------------------------------- 
|  1| Garage 1|  200| 
----------------------------------- 
|  2| Garage 2|  400| 
----------------------------------- 

Autos Tabelle:

--------------------------- 
|car_id|car_name|garage_id| 
--------------------------- 
|  1| Car 1|  1| 
--------------------------- 
|  2| Car 2|  1| 
--------------------------- 
|  3| Car 3|  2| 
--------------------------- 

Wertpapiere Tabelle:

---------------------------------- 
|security_id|security_name|car_id| 
---------------------------------- 
|   1| Security 1|  1| 
---------------------------------- 
|   2| Security 2|  1| 
---------------------------------- 
|   3| Security 3|  2| 
---------------------------------- 
|   4| Security 4|  3| 
---------------------------------- 

Der Ausgang muss sein:

Security 1 is on Garage 1 
Security 2 is on Garage 1 
Security 3 is on Garage 1 
Security 4 is on Garage 2 

Und ich habe die Modelle:

Der Code ist die Garagen zur Liste, aber ich mag ähnlich machen, aber die Wertpapiere zur Liste (nur für Sie eine Vorstellung davon haben, wie die Struktur ist) .

$garages = Garages::with(['cars', 'securities'])->get(); 

$garages->transform(function($garages) { 
    return array(
     'garage_name'  => $garage->garage_name, 
     'count_cars'  => $garage->cars->count(), 
     'count_securities' => $garage->securities->count(), 
    ); 
}); 

class Garages extends Eloquent 
{ 
    public function cars() 
    { 
     return $this->hasMany('cars'); 
    } 

    public function securities() 
    { 
     return $this->hasMany('securities'); 
    } 
} 

class Cars extends Eloquent 
{ 
} 

class Securities extends Eloquent 
{ 
} 

Und wieder einen Schwerpunkt zu machen: Ich mag den Namen der Garage Zusammenhang mit dem Auto haben, die die Sicherheit sicher hält.

Nur um es noch einfacher zu verstehen, wenn ich dies tun:

$securities = Securities::with(['cars'])->get(); 

class Securities extends Eloquent 
{ 
    public function cars() 
    { 
     return $this->hasOne('cars'); 
    } 
} 

Ich werde nur die garage_id aus cars Tabelle als Beziehungen erhalten. Was ich wirklich will, ist der Name der Garage.

[relations:protected] => Array 
    (
     [cars] => Cars Object 
      (
       ... 
       [attributes:protected] => Array 
        (
         ... 
         [car_name] => Car 1 
         [garage_id] => 1 
         ... 

Antwort

19

Es sieht aus wie Sie sind nicht Objekte korrekt beziehen. Lassen Sie uns das aufgliedern:

Wenn ein Garage Viele Hat Car dann ein Car gehört Garage To, Fangen wir mit dieser Idee im Kopf stattfindet.

  • Garage hat viele Car
  • Car Viele Hat Security
  • Security gehört Car
  • Garage hat viele Security Durch Car

In Eloquent Sie einfach weitermachen können und diese Wieder klatschen In dem Schema, das Sie oben gepostet haben, sollte es funktionieren.

class Garage extends Eloquent 
{ 
    public function cars() 
    { 
     return $this->hasMany('cars'); 
    } 

    public function securities() 
    { 
     return $this->hasManyThrough('Security', 'Car'); 
    } 
} 

class Car extends Eloquent 
{ 
    public function securities() 
    { 
     return $this->hasMany('Security'); 
    } 

    // ADDED IN SECOND EDIT 

    public function garage() 
    { 
     return $this->belongsTo('Garage'); 
    }  
} 

class Security extends Eloquent 
{ 
    public function car() 
    { 
     return $this->belongsTo('Car'); 
    } 
} 

Und das sollte es sein.

EDIT: Sie können auf alle diese Beziehungen von jedem Modell zugreifen, solange es einen Pfad gibt, den Sie mithilfe einer Kombination dieser Beziehungen von einem Modell zu einem anderen zeichnen können. Check this out zum Beispiel:

$security = Security::with('car.garage')->first(); 

zuerst Security Datensatz abrufen und laden Car Beziehung auf sich, dann geht es einen Schritt weiter und laden alle Garage Beziehungen auf jedem Car Objekt geladen unter Security Modell.

Sie können sie Zugriff auf diese Syntax:

$security->car->garage->id 

// Other examples 
$garage = Garage::with('cars.securities')->first(); 

foreach($garage->cars as $car) 
{ 
    foreach($cars->securities as $security) 
    { 
     echo "Car {$car->id} has {$security->id} assigned to it"; 
    } 
} 

Des Weiteren bekannt, dass die Beziehung Objekte sind eine Instanz von Collection so haben Sie alle ausgefallenen Methoden wie ->each(), ->count(), ->map() auf ihnen zur Verfügung.

+0

I verstehe nicht, wie ich jetzt den Namen der Garage abrufen werde. Denn wenn ich das mache: '$ securities = Securities :: with (['cars']) -> get();' gibt immernoch nur die ID des Benutzers zurück. – yayuj

+0

Sie können Beziehung mit Punktoperator verschachteln, wie folgt: 'Sicherheit :: mit ('Auto', 'Car.Garage')' – Gufran

+0

@MrAlmighty Ich habe die Antwort bearbeitet, um weitere Informationen hinzuzufügen. geh nochmal durch. – Gufran

7

Ich lief in ein ähnliches Problem vor kurzem und war in der Lage, so etwas zu tun:

class Cars extends Eloquent 
{ 
    public function garage() 
    { 
     return $this->hasOne('Garages'); 
    } 
} 

class Securities extends Eloquent 
{ 
    public function car() 
    { 
     return $this->hasOne('Cars'); 
    } 

    public function garage() 
    { 
     return $this->car->garage(); 
    } 
} 

Dies gibt Ihnen die Wertpapiere haben eine Garage Beziehung und man kann so etwas tun:

$securities = Securities::with('garage')->get(); 

foreach($securities as $security) 
{ 
    echo $security->security_name . ' is on ' . $security->garage->garage_name; 
}