fetch() vrací Table\Selection namísto ActiveRow

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
kazlik
Člen | 19
+
0
-

Zdravím, mám problém s jedním dotazem. Mám dva velmi podobné dotazy v proměnných $change a $looser. Funkce provádí to, že „prohodí“ pozice dvou prvků (první je daný pomocí ID a druhý se zjistí podle pozice prvního +/- 1 pozice. Část, kde se pozice prohazují zde není uvedena (stačí, že dump($looser); hází Selection místo ActiveRow).

public function moveItem($direction, $id, $table){
  //Fotka, kterou posouváme
  $change = $this->database->table($table)
    ->where('id', $id)
    ->fetch();
  //Oběť, která musí být posunuta
  $looser = $this->database->table($table);
  //Pro nastavení podmínek pro jednotlivé tabulky
  switch($table){
    case 'product_detail':
      $looser->where('language_id', $change->language_id);
    break;
  }
  if($direction == 'up'){
    $looser->where('position', $change->position - 1);
  }else if($direction == 'down'){
    $looser->where('position', $change->position + 1);
  }
  $looser->fetch();
  dump($change);
  dump($looser);
}

Když si vezmeme, že position = id, tak se vykonají dotazy pro posun nahoru (prvek s ID 6 na 6. pozici chceme přesunout na 5. pozici)

Prvek který chceme přesunout:

SELECT `id`, `language_id`, `position`, `name`
FROM `product_detail`
WHERE (`id` = '6')

Oběť, která se nachází o pozici výš nad prvkem k přesunutí (po vložení do Admineru správně vybere řádek s ID = 5):

SELECT `id`
FROM `product_detail`
WHERE (`language_id` = 1) AND (`position` = 5)

Oba dotazy v TRACY zobrazují 1 vrácený výsledek, akorát dump($change); vrací ActiveRow a dump($looser); vrací Selection.
Nevíte, co způsobuje jiné chování objektu $looser?

Oli
Člen | 1215
+
+2
-
$looser = $looser->fetch();
// nebo
dump($looser->fetch());
kazlik
Člen | 19
+
0
-

Díky, funguje to :) Jen nechápu toto jiné chování (proč to nefunguje klasicky). Objasníte mi to trošku?

CZechBoY
Člen | 3608
+
0
-

Metoda fetch vrací ActiveRow, nemění $this – taky to snad ani nejde vložit do $this jinou instanci než v jaké třídě je vytvořena.

Oli
Člen | 1215
+
0
-

Ono se to takhle chová klasicky. Jde o to, že základní typy (int, string, bool, …) se „drží své“ proměnné. Tzn:

$a = 1;
$a++;
$b = $a;
dump($a) // 2
dump($b) // 2

Zatímco objekty odkazují někam do paměti a ty si musíš předat do nové proměnné ten nový stav na který ukazuješ

$a = new Object();
$another = $a->loadAnother() //return instance of Another
dump($a) // Object
dump($another) // Another
ViPEr*CZ*
Člen | 809
+
0
-

Nevíte, co způsobuje jiné chování objektu $looser?

Osobně jsem nepochopil ani jeden dotaz.
Jiné chování? Jaké jiné chování?
Vy si vytvoříte instanci Selection zde

$looser = $this->database->table($table);

Pak nad tímto objektem voláte jeho členské funkce where a fetch.
Kde vidíte nějaké jiné chování?
Metoda where a fetch mají tak maximálně návratové hodnoty, které si můžete zachytit (přiřadit) do proměnné. Podle jejich dokumentace pak zjistíte jakého typu jsou ty návratové hodnoty.
Where vrací tuším ukazatel na sama sebe – tedy this. A fetch pak ActiveRow nebo false tuším.

Klasické chování jazyka. Třída má členské metody a ty mohou mít návratové hodnoty.
Pak tu je ještě klíčové slovo this, což představuje ukazatel na sama sebe.

kazlik
Člen | 19
+
0
-

Už to chápu, $change vzhledem k tomu, že dotaz není rozkouskován +fetch() je ihned ActiveRow, zatímco u $looser je Selection, kterou je potřeba přepsat na ActiveRow.
Díky moc všem :)

ViPEr*CZ*
Člen | 809
+
+1
-

kazlik napsal(a):

Už to chápu, $change vzhledem k tomu, že dotaz není rozkouskován +fetch() je ihned ActiveRow, zatímco u $looser je Selection, kterou je potřeba přepsat na ActiveRow.
Díky moc všem :)

Jj tak nějak. Ale není samozřejmě potřeba looser přepsat jak ukázal @Oli, ale můžeš si jí třeba předat do nějaké nové proměnné. Protože třeba zkrátka tu instanci Selection budeš o něco málo níže ještě potřebovat.