Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Laravel Eloquent foreach i save
Forum PHP.pl > Forum > PHP > Frameworki
markonix
  1. $i = 0;
  2. $trainings->each(function($training) use ($i) {
  3. dump($training->id);
  4. $training->topic = ++$i;
  5. $training->save();
  6. });


Czy użyje foreach czy each to nie zadziała. W $trainings mam ładną kolekcję obiektów Training zwróconą za pomocą ->get().
Samo $training->topic działa, nadpisze atrybuty ale gdy użyje to wraz save() to wszystko się psuje - dump zwraca za każdym razem id pierwszego obiektu.

Nie umiem zrozumieć dlaczego to nie działa? Jakieś rozwiązania na szybko bym znalazł (skorzystać z QB czy tworzyć w każdym obrocie pętli $obj = new Training::find($training->id) ale to by było mega słabe (na każdy obrót pętli 2 zapytania).

Generalnie najbardziej optymalnie by było coś w stylu:
  1. $i = 0;
  2. $trainings->each(function($training) use ($i) {
  3. dump($training->id);
  4. $training->topic = ++$i;
  5. });
  6.  
  7. $trainings->save();

Ale to już bardziej rozumiem, że nie przechodzi (ale nie ukrywam, było by miło jakby był też sposób aby w ten sposób masowo updatejtnąć wszystkie obiekty).
Pyton_000
A:
  1. $i = 0;
  2. $trainings->each(function($training) use ($i) {
  3. $training->update([
  4. 'topic' => ++$i
  5. ]);
  6. });
markonix
Gdy się położyłem to mi się dopiero żarówka zaświeciła.
Generalnie ta cała akcja służy reindeksacji pewnej kolumny przy delete/update/insert. Dla delete i insert nie ma problemu jednak problem przychodzi przy update.
  1. static::updated(function($training) {
  2. static::reindex($training->date);
  3. });

Używając eloquent spowoduje zapętlenie - update użytkownika odpala metodę reindex(), która odpala event. Podpowiedzią był error 500 zwracany przez ajax.
Pytanie jak do tego teraz fajnie podejść. Użycie Query buildera generalnie rozwiązuje problem, jako, że on nie odpala eventów.
nospor
Zacznij prosze zakladac tematy we wlasciwym dziale. Przenosze
markonix
Problem i tak się okazał "ponad frameworkowy". Zapętlenie się eventów na update to raczej problem logiczny wink.gif
nospor
Nie mniej jednak mocno dotyczylo to jak dziala Laravel i eloquent wink.gif
Pyton_000
Możesz wywalić eventy dając `Training::flushEventListeners();`
markonix
Ostatecznie podszedłem do tego bardziej skomplikowanie.
Wyłuskałem z dokumentacji ciekawe metody isDirty() i getOriginal() i wykonuje tylko reIndex w momencie gdy zmieniła się godzina.
Przy okazji jest to też rozwiązanie na problem na który bym wcześniej nie zwrócił uwagi - reindeks działał każdorazowo tylko na NOWĄ datę, a przy zmianie daty jest on potrzebny także dla oryginalnego dnia.
Tak więc ostateczny kod:

  1. static::updated(function($training) {
  2. if ($training->isDirty('hour')) {
  3. static::reindexTrainings($training->date);
  4. }
  5. if ($training->isDirty('date')) {
  6. static::reindexTrainings($training->getOriginal('date'));
  7. }
  8. });
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.