2015-02-05 13 views
5

Chcę ustawić określony atrybut we wszystkich modelach kolekcji.Wymowne - Aktualizowanie wszystkich modeli w kolekcji

w czystym SQL:

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

kod mam:

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

zaczerpnięte z here

ale nie działa. Dostaję

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

jedyny sposób znalazłem to budowanie kwerendy z konstruktora zapytań ale wolałbym tego uniknąć.

+0

Eonquent to program budujący zapytania, a nie ORM. Nie definiuje 'aktualizacji' na instancjach modelu.Możesz to zdefiniować samemu, ale na końcu gdzieś w kodzie musisz wpisać 'MyModel :: whereIn ('id', [1, 2, 3]) -> update (...)'. –

+1

@SergiuParaschiv Właściwie Eloquent to ORM – lukasgeiter

+1

Po prostu logowałem to samo pytanie. Hai ~ – JSelser

Odpowiedz

13

Zwracasz kolekcję, a zapytanie nie jest otwarte na aktualizację. Podobnie jak twój przykład.

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

whereIn wyśle ​​zapytanie kolumnę w przypadku id, drugi parametr jest tablicą identyfikatorów chcesz wrócić, ale nie wykona zapytanie. Użyty przez Ciebie findMany wykonał go w ten sposób, zwracając kolekcję modeli.

Jeśli potrzebujesz modelu do użycia do czegoś innego, możesz zrobić $collection = $models->get(); i zwróci kolekcję modeli.

Jeśli po prostu nie napiszesz tego w jednym wierszu, tak jak;

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

Inną opcją, której nie polecam, jest użycie poniższych;

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

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

Spowoduje to zapętlenie wszystkich elementów w kolekcji i zaktualizowanie ich pojedynczo. Ale polecam metodę whereIn.

+0

zadziałała metoda 'whereIn'. ale co, jeśli mam kolekcję modeli. nie da się zaktualizować wszystkich naraz? – Jarry

+0

Nie, nie ma bez przechodzenia przez nie każdy dodałem, że jako opcja na końcu odpowiedzi, ale nie polecam tego. –

+0

nie, nie polecam tego, dlatego szukałem alternatywy – Jarry

2

Najlepszym rozwiązaniem w jednym zapytaniu jest nadal:

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

Jeśli masz już kolekcję modeli i chcesz zrobić bezpośredniej aktualizacji można użyć modelKeys() metody. Uważają, że po dokonaniu tej aktualizacji kolekcji $models pozostaje przestarzała i może trzeba go odświeżyć:

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

Następny przykład ja nie polecam, bo dla każdego elementu kolekcji $models nowa dodatkowa kwerenda jest wykonywana:

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

lub prostsze, od Laravel 5.4 można zrobić $models->each->update(['att'=>'foo']);

jednak ostatni przykład (i tylko ostatnia) jest dobre, gdy chcesz wywołać pewne modelowe wydarzeń, takich jak saving, saved, updating, updated. Inne prezentowane rozwiązania dotykają bezpośrednio bazy danych, ale modele nie budzą się.

Powiązane problemy