2015-02-05 12 views
5

Desidero impostare un determinato attributo in tutti i modelli di una raccolta.Eloquent - Aggiornamento di tutti i modelli di una collezione

in SQL pianura:

UPDATE table SET att = 'foo' WHERE id in (1,2,3) 

il codice che ho:

$models = MyModel::findMany([1,2,3]); 
$models->update(['att'=>'foo']); 

tratto da here

ma non funziona. Sto diventando

Call to undefined method Illuminate\Database\Eloquent\Collection::update() 

l'unico modo che ho trovato è la costruzione di una query con il generatore di query, ma io preferirei evitarlo.

+0

Eloquent è un generatore di query, non un ORM. Non definisce 'update' sulle istanze del modello.Puoi definirlo da solo, ma alla fine da qualche parte nel codice _your_ devi scrivere 'MyModel :: whereIn ('id', [1, 2, 3]) -> update (...)'. –

+1

@SergiuParaschiv In realtà Eloquent è un ORM – lukasgeiter

+1

Basta cercare su Google la stessa domanda. Hai ~ – JSelser

risposta

13

Si sta restituendo una raccolta, non mantenendo aperta la query per l'aggiornamento. Come sta facendo il tuo esempio.

$models = MyModel::whereIn('id',[1,2,3]); 
$models->update(['att'=>'foo']); 

whereIn interrogherà una colonna nel tuo caso id, il secondo parametro è un array degli ID che si desidera tornare, ma non eseguire la query. Il findMany che stavi usando stava eseguendolo restituendo così una collezione di modelli.

Se è necessario ottenere il modello per qualcos'altro, è possibile eseguire $collection = $models->get(); e restituirà una raccolta dei modelli.

Se non lo si scrive semplicemente su una riga in questo modo;

MyModel::whereIn('id',[1,2,3])->update(['att'=>'foo']); 

Un'altra opzione che non consiglio è l'utilizzo di quanto segue;

$models = MyModel::findMany([1,2,3]); 

$models->each(function ($item){ 
    $item->update(['att'=>'foo']); 
}); 

In questo modo verranno ripetuti tutti gli elementi della raccolta e aggiornati singolarmente. Ma raccomando il metodo whereIn.

+0

ha funzionato il metodo 'whereIn'. ma cosa succede se ho una collezione di modelli. non c'è modo di aggiornarli tutti in una volta? – Jarry

+0

No, non ce n'è stato senza averli esaminati, l'ho aggiunto come opzione alla fine della risposta, ma non lo consiglio. –

+0

no, non lo consiglio neanche, ecco perché stavo cercando un'alternativa – Jarry

2

La soluzione migliore in una singola query è ancora:

MyModel::whereIn('id',[1,2,3])->update(['att'=>'foo']); 

Se si dispone già di una collezione di modelli e si vuole fare un aggiornamento diretto è possibile utilizzare modelKeys() metodo. Si consideri che dopo aver fatto questo aggiornamento tua collezione $models rimane obsoleta e potrebbe essere necessario per aggiornarlo:

MyModel::whereIn('id', $models->modelKeys())->update(['att'=>'foo']); 
$models = MyModel::findMany($models->modelKeys()); 

Il prossimo esempio non vi consiglio perché per ogni elemento della vostra collezione $models viene eseguita una nuova query in più:

$models->each(function ($item) { 
    $item->update(['att'=>'foo']); 
}); 

o più semplice, da Laravel 5.4 si può fare $models->each->update(['att'=>'foo']);

Tuttavia, l'ultimo esempio (e solo l'ultimo) è buono quando si desidera attivare alcuni eventi come il modello saving, saved, updating, updated. Altre soluzioni presentate toccano direttamente il database ma i modelli non vengono svegliati.

Problemi correlati