2016-08-02 9 views
0

ich habe 2 Tabellen users und user_metafindOrNew gibt ein Array statt Objekt, wenn die Bedingung nicht auf id ist

in meinem users Modell ich habe

function meta() { 
    return $this->hasOne('App\userMeta'); 
} 

in meinem Controller, wenn ich Benutzer speichern möchten, und Benutzer meta

function store(Request $request , $id = 0) {  
    $user = User::findOrNew($id); 
    $user->save() ; 

    $meta = UserMeta::findOrNew(['user_id'=>$id]); 
    $user->meta()->save($meta);  
} 

wenn im meta zu speichern versuchen ich diesen Fehler erhalten

Argument 1 bestanden Illuminate \ Database \ Eloquent \ Relations \ HasOneOrMany :: save() muss eine Instanz von Illuminate \ Database \ Eloquent \ Model, sein

hier ist das Problem UserMeta::findOrNew(['user_id'=>$id]) eine zurück Array anstelle von Objekt ... das ist seltsam .. während User::findOrNew($id) selbst zurückkehrt und Objekt .... ich denke, es ist becuz meiner Bedingungen (es ist der einzige Unterschied zwischen 2 Abfrage)

gerade jetzt muss ich tun etwas wie das

$meta = UserMeta::findOrNew(['user_id'=>$id]); 
if(is_array($meta)) { 
    $user->meta()->save($meta[0]); 
} else { 
    $user->meta()->save($meta); 
} 

was ich nicht mag und falsch aussieht!

+0

Vielleicht 'UserMeta' hat mehrere Zeilen mit der gleichen' user_id' – jonju

+0

@jonju nein es ist eine 1to1 Beziehung so Datenbank wird nicht akzeptiert, die gleiche user_id mehr als einmal – hretic

+0

Aber dies nicht 'HasOneOrMany" aussehen One-to-One-Beziehung. – jonju

Antwort

3

Die Funktion findOrNew() ist wahrscheinlich nicht das, was Sie suchen. Es soll verwendet werden, wie folgt:

// the array in the second parameter specifies which columns are 
// included in the resulting model (if found) 
// it is NOT used as a WHERE clause 
$meta = UserMeta::findOrNew($id, ['user_id'=>$id]); 

Was Sie suchen:

// adds where clause (returns new model if it does not exist) 
$meta = UserMeta::firstOrNew(['user_id' => $id]); 

// same as above but persists new model to database 
$meta = UserMeta::firstOrCreate(['user_id' => $id]); 

Grund, warum firstOrNew() in Ihrem Fall kein einheitliches Modell zurück:

Diese ist die Implementierung von findOrNew Illuminate \ Database \ Eloquent \ Builder.php:

public function findOrNew($id, $columns = ['*']) 
{ 
    if (! is_null($model = $this->find($id, $columns))) { 
     return $model; 
    } 

    return $this->model->newInstance(); 
} 

Wie Sie sehen, ist der erste Parameter nicht für die Spalten vorgesehen.

Wenn Sie einen Blick auf die Methode find in $ this- haben> finden ($ id, $ Spalten) Sie sehen:

public function find($id, $columns = ['*']) 
{ 
    if (is_array($id)) { 
     return $this->findMany($id, $columns); 
    } 

    $this->query->where($this->model->getQualifiedKeyName(), '=', $id); 

    return $this->first($columns); 
} 

Als Ihr übergeben ein Array als $ id das Ergebnis von $ this-> findMany() wird zurückgegeben, was eine Collection ist.

+0

ich sah, so können wir nicht ändern WHERE-Klausel in der findOrNew? – hretic

+0

genau es sucht nur nach ID (s) oder was auch immer Sie als Primärschlüssel Spaltenname definiert haben –

1

Vielleicht sollten Sie FirstOrCreate anstelle von findOrNew verwenden.

+0

thanx überwunden, das wäre Plan B – hretic

+0

'findOrNew' verhält sich gleichzeitig anders. Und laut OP ist es eine Eins-zu-Eins-Beziehung. Es sollte funktionieren, wie es im Falle der "Benutzer" – jonju