2016-02-08 6 views
11

Ich habe eine timesheet Tabelle und eine user Tabelle in meiner Datenbank. Die folgende Beziehung wird auf dem Modell timesheet eingerichtet.Laravel 5.1 laden Beziehungsdaten in ausgewählte Zeile

/** 
* The user that owns the timesheet. 
* 
* @return Object 
*/ 
public function user() 
{ 
    return $this->belongsTo('App\Models\User\User'); 
} 

Die oben genannte Mittel I Benutzerdaten erhalten kann, wenn ich Zeiterfassungen aus der Datenbank auswählen, indem Sie mit so etwas wie:

$this->timesheet->whereStatus('Approved')->with('user'); 

Dadurch wird das Benutzerobjekt im Ergebnis laden und wenn umgewandelt in ein Array wird so aussehen;

0 => array:13 [▼ 
    "id" => 1 
    "user_id" => 2 
    "week" => 1 
    "year" => 2016 
    "week_ending" => "Sunday 10th January 2016" 
    "total_hours" => "45.00" 
    "token" => "0e6796a2dc68066c8d36ff828c519af00657db02b733309b8a4ac0f7b5d6a385" 
    "status" => "Approved" 
    "supervisor_id" => 1 
    "approved_by" => 1 
    "created_at" => "2016-01-13 15:42:49" 
    "updated_at" => "2016-01-14 14:52:07" 
    "user" => array:7 [▼ 
     "id" => 2 
     "first_name" => "Bill" 
     "last_name" => "Andrews" 
     "email" => "[email protected]" 
     "status" => 1 
     "created_at" => "2016-01-13 15:38:18" 
     "updated_at" => "2016-01-14 14:50:03" 
    ] 
    ] 

Ich brauche aber nur first_name und last_name aus der Benutzertabelle. Gibt es eine Möglichkeit, das Array user mit dem timesheet zusammenzufassen/abzuflachen, so dass es stattdessen so aussieht;

0 => array:14 [▼ 
    "id" => 1 
    "user_id" => 2 
    "week" => 1 
    "year" => 2016 
    "week_ending" => "Sunday 10th January 2016" 
    "total_hours" => "45.00" 
    "token" => "0e6796a2dc68066c8d36ff828c519af00657db02b733309b8a4ac0f7b5d6a385" 
    "status" => "Approved" 
    "supervisor_id" => 1 
    "approved_by" => 1 
    "created_at" => "2016-01-13 15:42:49" 
    "updated_at" => "2016-01-14 14:52:07" 
    "first_name" => "Bill" 
    "last_name" => "Andrews" 
    ] 

Ich habe versucht, eifrig laden wie so zu verwenden;

$this->timesheet->with(['user' => function ($query) { 
    $query->select('first_name', 'last_name'); 
}])->get()->toArray(); 

Jedoch führt es in der folgenden Ausgabe;

array:126 [▼ 
    0 => array:13 [▼ 
    "id" => 1 
    "user_id" => 2 
    "week" => 1 
    "year" => 2016 
    "week_ending" => "Sunday 10th January 2016" 
    "total_hours" => "45.00" 
    "token" => "0e6796a2dc68066c8d36ff828c519af00657db02b733309b8a4ac0f7b5d6a385" 
    "status" => "Approved" 
    "supervisor_id" => 1 
    "approved_by" => 1 
    "created_at" => "2016-01-13 15:42:49" 
    "updated_at" => "2016-01-14 14:52:07" 
    "user" => null 
    ] 

Antwort

7

Der Grund, warum die Benutzerbeziehung in Ihrem zweiten Beispiel null ist, liegt darin, dass für das Funktionieren von Eloquent Relations die Schlüssel benötigt werden, die die Beziehungen verknüpfen. Mit anderen Worten ...

  1. Get timesheet.
  2. Get user mit nur first_name und last_name.
  3. Build-Beziehung.
  4. Da Sie die ID des Benutzers nicht abgerufen haben, stimmen die user's id und die timesheet's user_id nicht überein, so dass die Beziehung nicht erstellt werden kann.

Um Ihre Frage zu arbeiten, können Sie es so einstellen müssen:

$this->timesheet->with(['user' => function ($query) { 
    $query->select('id', 'first_name', 'last_name'); 
}])->get()->toArray(); 

Mit diesem aus dem Weg, wenn Sie eine abgeflachte Ergebnis wollen, denke ich, ist es am besten joins verwenden eher als eifriges Laden wegen der Natur des eifrigen Ladens.

$this->timesheet 
    ->join('users', 'timesheets.user_id', '=', 'users.id') 
    ->select('timesheets.*', 'users.first_name', 'users.last_name') 
    ->get()->toArray(); 

Dies setzt voraus, dass Ihre Tabellennamen users und timesheets sind.

+0

Danke für Ihre Hilfe, dies ist die Information, die ich suchte. Ich werde in 9 Stunden Kopfgeld geben (es sagt mir, dass ich bis dahin nicht vergeben kann). – V4n1ll4

2

haben Sie eine Liste

->lists('first_name', 'last_name'); 

zu erhalten versucht oder wenn Sie verwandte eine ausgewählte

->select('first_name', 'last_name')->get() 

aktualisieren Sie können auch ausführen eifrig Laden zu eifrig Last ausführen wollte Objekte. Hier ist ein Beispiel

$users = App\User::with(['posts' => function ($query) { 
    $query->select('first_name', 'last_name'); 

}])->get(); 

Bitte lassen Sie mich wissen, wenn das hilft.

+0

Wenn Sie denken, ich habe Ihre Frage richtig beantwortet, können Sie dies bitte als die richtige Antwort für den nächsten Mann bitte markieren. Vielen Dank ! – Gagan

+0

Ich habe '$ rows-> Listen ('week_ending', 'user.first_name', 'user.last_name', 'created_at', 'total_hours', 'status') ausprobiert;' dies ist eine Liste der Spalten, die ich brauche , aber es gibt einfach zurück "" Bill "=>" Sonntag, 10. Januar 2016 "' – V4n1ll4

+0

Bitte siehe obigen Ausgang (ich habe meinen ursprünglichen Beitrag aktualisiert) nach dem eifrigen Laden. – V4n1ll4

-1

In diesem Fall ist es besser, Raw SQL oder Query Builder zu verwenden. Da Beziehungen für die Verwendung von Datenbankdaten als relationale Objekte erstellt wurden.

1

Das ist genau das, was eine join tun.

From the documentation

Der Query Builder kann auch verwendet werden, schreiben Aussagen zu kommen. Um eine grundlegende SQL "innere Verknüpfung" auszuführen, können Sie die Join-Methode für eine Abfrage-Builder-Instanz verwenden. Das erste an die Join-Methode übergebene Argument ist der Name der Tabelle, der Sie beitreten müssen, während die verbleibenden -Argumente die Spalteneinschränkungen für den Join angeben.

$this->timesheet 
     ->leftjoin('user', 'user.id', '=','timesheet.user_id') 
     ->get() 
     ->toArray(); 

Wenn Sie auf Ihre Felder sein selektiver möchten, können Sie wählen, was Sie select;

$this->timesheet 
     ->leftjoin('user', 'user.id', '=','timesheet.user_id') 
     ->select('timesheet.*', 'user.first_name', 'user.last_name') 
     ->get() 
     ->toArray(); 

Wie andere vorgeschlagen haben, könnte es besser sein, die DB Query Builder zu verwenden, wie

this->timesheet = DB::table('timesheet') 
       ->where('timesheet.status', 'Approved') 
       ->leftjoin('user', 'user.id', '=','timesheet.user_id') 
       ->select('timesheet.*', 'user.first_name', 'user.last_name') 
       ->get() 
       ->toArray(); 
2

Laravel Modelle haben eine Möglichkeit, Daten zu ändern, bevor sie/ein Attribut festlegen. Sie können die Attribute tatsächlich dem Modell hinzufügen, indem Sie eine Getter-Funktion definieren. Auf diese Weise können Sie die Benutzernamen auf die gleiche Weise wie die user_id oder status referenzieren. Diese Funktionen eignen sich auch hervorragend zum Ändern von Datumsformaten für eine Ansicht oder zum Bereinigen von Formulareingaben.

/** 
* Get the first name of the user. 
* 
* @return string 
*/ 
public function getFirstNameAttribute() 
{ 
    return $this->user->first_name; 
} 

/** 
* Get the last name of the user. 
* 
* @return string 
*/ 
public function getLastNameAttribute() 
{ 
    return $this->user->last_name; 
}