wake-up-neo.com

Hat man durch Laravel Eloquent

Ich habe drei Tabellen garages, cars, securities.

Bei den Wertpapieren handelt es sich um diejenigen, die ein Auto sicher halten. Sie können mehr als ein Wertpapier haben, aber ein einzelnes Wertpapier kann nur ein Auto sicher halten. In der Garage steht das Auto und auch die Sicherheiten.

Was ich will, ist, alle Wertpapiere aufzulisten und den Namen der Werkstatt zu kennen, die er ist. Das Problem ist, dass securities keine Spalte enthält, die die ID der Garage enthält, sondern nur die ID des Autos, das er sicher verwahrt, aber das Auto hat die ID der Garage.

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

Hier sind die Tabellen:

garagentisch:

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

autos tisch:

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

wertpapier-Tabelle:

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

Die Ausgabe 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 aufzulisten, aber ich möchte ähnlich machen, aber die Wertpapiere auflisten (nur damit 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 um es noch einmal zu betonen: Ich möchte den Namen der Garage in Bezug auf das Auto haben, das die Sicherheit schützt.

Nur um es noch verständlicher zu machen, wenn ich das mache:

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

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

Ich werde nur den garage_id Aus der Tabelle cars als Relationen 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
                        ...
26
yayuj

Es sieht so aus, als würden Sie Objekte nicht richtig in Beziehung setzen. Lassen Sie uns das zusammenfassen:

Wenn eine Garage viele Car hat, dann gehört eine Car zu Garage, lassen Sie uns mit dieser Idee fortfahren.

  • Garage hat viele Car
  • Car hat viele Security
  • Security Gehört zu Car
  • Garage hat viele Security bis Car

In Eloquent können Sie einfach vorgehen und diese Relationen einklatschen. Dies sollte in Anbetracht des oben angegebenen Schemas 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 von jedem Modell aus auf alle diese Relationen zugreifen, solange es einen Pfad gibt, den Sie mit einer Kombination dieser Relationen von einem Modell zum anderen zeichnen können. Überprüfen Sie dies zum Beispiel:

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

ruft zuerst die Security Aufnahme ab und lädt die Car Beziehung darauf, geht dann einen Schritt weiter und lädt alle Garage Beziehungen auf jede Car Objekt geladen unter Security Modell.

Sie können mit dieser Syntax darauf zugreifen:

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

Beachten Sie außerdem, dass die Beziehungsobjekte eine Instanz von Collection sind, sodass Sie über alle ausgefallenen Methoden wie ->each(), ->count(), ->map() verfügen. verfügbar auf ihnen.

33
Gufran

Ich bin kürzlich auf ein ähnliches Problem gestoßen und konnte Folgendes 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 Securities hat eine Garage Beziehung und Sie können etwas tun wie:

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

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

Dies ist relevant für Ihre ursprüngliche Anfrage.

hasOneThrough wird in Laravel 5.8 verfügbar sein

https://github.com/laravel/framework/pull/26057/files

6
danrichards