2014-12-14 15 views
11

Mam trzy tabele garages, cars, securities.Ma jeden przez Laravel Wymowne

Papiery wartościowe zabezpieczają jeden samochód, można mieć więcej niż jedno zabezpieczenie, ale jedno zabezpieczenie może zabezpieczyć tylko jeden samochód. Garaż jest tam, gdzie jest samochód, a także papiery wartościowe.

Chcę tylko wymienić wszystkie papiery wartościowe i znać nazwę garażu, którym jest. Problem polega na tym, że securities nie ma kolumny zawierającej identyfikator garażu, a jedynie identyfikator samochodu, który zapewnia, ale samochód ma identyfikator garażu.

Laravel Eoquent ma metodę o nazwie hasManyThrough, ale securities ma tylko jedną garage do cars.

Oto tabele:

garaże tabela:

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

samochody tabela:

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

stół papiery wartościowe:

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

wyjście musi być:

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

i mam modele:

Kod jest notować garaże, ale chcę, aby podobne, ale do listy papierów wartościowych (tak, aby mieć pomysł, jak struktura jest) .

$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 
{ 
} 

I tak, aby nacisk znowu: chcę mieć nazwę związaną z garażu samochód, że bezpieczeństwo jest utrzymując bezpieczny.

Wystarczy, aby jeszcze łatwiej zrozumieć, jeśli mogę to zrobić:

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

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

dostanę tylko garage_id od cars stół jako relacji. To, czego naprawdę chcę, to nazwa garażu.

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

Odpowiedz

19

Wygląda na to, że nie łączysz obiektów prawidłowo. Złammy że dół:

Jeśli Garage ma wiele Car następnie Car Należy Do Garage, pozwala kontynuować tej idei w umyśle.

  • Garage ma wiele Car
  • Car ma wiele Security
  • Security Należy Do Car
  • Garage ma wiele Security Poprzez Car

W wymowny można po prostu iść do przodu i klaskać te re lacje, powinno działać zgodnie ze schematem zamieszczonym powyżej.

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

To powinno być to.

EDYCJA: Możesz uzyskać dostęp do wszystkich tych relacji z dowolnego modelu, o ile istnieje ścieżka, którą możesz przeciągnąć z jednego modelu do drugiego, używając kombinacji tych relacji. Sprawdź to na przykład:

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

pobierze pierwszy Security rekord i załadować Car relację na niego, a następnie idzie jeszcze jeden krok i załadować wszystkie Garage relacji na każdym Car obiektu załadowanego pod Security modelu.

Można uzyskać do nich dostęp za pomocą tej składni:

$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"; 
    } 
} 

Ponadto należy zauważyć, że obiekty relacje są instancją Collection więc masz wszystkie wymyślne metody, takie jak ->each(), ->count(), ->map() dostępnych na nich.

+0

I nie rozumiem, jak mam teraz odzyskać nazwę garażu. Ponieważ jeśli to zrobię: '$ securities = Securities :: with (['cars']) -> get();' nadal zwraca tylko identyfikator użytkownika. – yayuj

+0

Można nawiązywać relacje za pomocą operatora dot, na przykład: 'Security :: with ('car', 'car.garage')' – Gufran

+0

@MrAlmighty Edytowałem odpowiedź, aby dodać więcej informacji. powtórz to jeszcze raz. – Gufran

7

wpadłem na podobny problem niedawno i był w stanie zrobić coś takiego:

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

Daje to Papiery ma jeden związek garażu i można zrobić coś takiego:

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

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