Přechod na verzi 2.2.0 a problém s related a ref

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

Ahoj,

spustil jsem nový nette 2.2.0 a snažil se rozběhnout stejný kód, který jsem měl v předchozí verzi

Bohužel mi to začalo hlásit tuto chybu:
Call to undefined method Nette\Database\Table\Selection::related()

Presenter:

public function renderDefault()
	{
		$smenu = $this->smenu->selectBySuperiror(null);
		$this->smenu->selectTranslateByRow($smenu);
		$this->template->smenu = $smenu;
	}

Model:

public function selectTranslateByRow($row)
{
	foreach ($row as $item) {
	$item['smenutranslation'] = $item->related('smenutranslation')->where("language_idlanguage", 1)->fetch();
	}
}

public function selectBySuperiror($superior)
{
	return $this->connection->table('smenu')->where("smenu.smenu_idsmenu", $superior);
}

Hledal jsem různě a nevím jak to řešit. Nejde mi klasicky použít jak related tak ref.

Za každou radu či pomoc mockrát díky
Míra

David Matějka
Moderator | 6445
+
0
-

chyba se urcite deje na radku

 $item['smenutranslation'] = $item->related('smenutranslation')->where("language_idlanguage", 1)->fetch();

jo?

co obsahuje promenna $row, ktera vstupuje do ty metody?

EDIT: nebo sem hod ladenku

Editoval matej21 (16. 5. 2014 12:58)

Miri
Člen | 117
+
0
-

No proměnná row obsahuje toto:

$this->connection->table('smenu')->where("smenu.smenu_idsmenu", $superior);

Laděnka:

Nette\MemberAccessException

Call to undefined method Nette\Database\Table\Selection::related(). search►

Source file

File: /var/www/clients/client1/web63/web/www/subdom/stacey2/vendor/nette/utils/src/Utils/ObjectMixin.php:97

 87:                return $_this;
 88:
 89:            } elseif ($cb = self::getExtensionMethod($class, $name)) { // extension methods
 90:                array_unshift($args, $_this);
 91:                return Callback::invokeArgs($cb, $args);
 92:
 93:            } else {
 94:                if (method_exists($class, $name)) { // called parent::$name()
 95:                    $class = 'parent';
 96:                }
 97:                throw new MemberAccessException("Call to undefined method $class::$name().");
 98:            }
 99:        }

Jde o to že nejde ani toto:

$test = $this->smenu->selectBySuperiror(null);
	foreach ($test->related('smenutranslation.smenu_idsmenu') as $item) {
}

Napsané podle předlohy v dokumentaci

David Matějka
Moderator | 6445
+
0
-

posli prosim celou rozklikavaci ladenku (html), tohle je k nicemu..

to druhy by jit ani nemelo, selectBySuperiror vraci Selection, ne ActiveRow

s4muel
Člen | 92
+
0
-
$test = $this->smenu->selectBySuperiror(null);
    foreach ($test->related('smenutranslation.smenu_idsmenu') as $item) {
}

toto ani nepojde, pretoze $test obsahuje selection a nad nim nejde robit related(), ten sa da nad ActiveRow

ale neviem, preco nejde ten prvy priklad, na prvy pohlad to vyzera OK.
skus to uplne zjednotusit na:

$menus = $this->connection->table('smenu')->where("smenu.smenu_idsmenu", null);
dump(get_class($menus)); //tu by mal dumpnut "Nette\Database\Table\Selection"
foreach($menus as $menu) {
	//tu by mal X krat dumpnut "Nette\Database\Table\ActiveRow"
	dump(get_class($menu));
	//tu by mal dupnut prvy related translation pre to menu
	dump($menu->related('smenutranslation')->where("language_idlanguage", 1)->fetch());
}
Miri
Člen | 117
+
0
-

s4muel:
Supr, tvé řešení začlo fungovat, poté jsem se vrátil k původnímu dal jsem tomu taky dump a z neznámého důvodu to začlo fungovat taky.

Ovšem když to chci zapsat

$item['smenutranslation'] = $item->related('smenutranslation')->where("language_idlanguage", 1)->fetch();

Hlasí to chybu
ActiveRow is read-only; use update() method instead

Nějaké rady jak se řeší jednoduše toto, nebo nějaké obdobné řešení? Jinak mockrát díky za vyřešení prvního problému.

Miri
Člen | 117
+
0
-

Resp.
Dá se nějak pooté přistupvoat k smenutranslation?

public function selectTranslateByRow($row)
{
    foreach ($row as $item) {
    	$item->related('smenutranslation')->where("language_idlanguage", 1)->fetch();
    }
}

Jako že nějak takto:

{foreach $smenu as $item}
	$item->smenutranslation->value}
{/foreach}

Editoval Miri (16. 5. 2014 14:15)

wodCZ
Člen | 49
+
0
-

Miri napsal(a):
Ovšem když to chci zapsat

$item['smenutranslation'] = $item->related('smenutranslation')->where("language_idlanguage", 1)->fetch();

Chyba popisuje přesně co je špatně: $item je read-only. Tím $item['smenutranslation'] = ... chceš zapisovat do read-only.
Jednoduše použij jinou proměnnou.
Nepochopil jsem strukturu/čeho chceš docílit, takže ti blíž neporadím.

o5
Člen | 416
+
0
-

Nevíte někdo jak je to v aktuální verzi NDB s where na spojovanou tabulkou která nemá pojmenovaný klíč dle konvencí?

->where(':updated_user_id.user.name');

Takto bych to očekával :))

David Matějka
Moderator | 6445
+
0
-

@o5: ukaz schema a odkud kam potrebujes propojit, z toho tveho prikladu to nechapu :)

o5
Člen | 416
+
0
-

@matej21: promazal jsem zbytečnosti

CREATE TABLE `article` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `user_id` INT NULL,
  `updated_user_id` INT NULL,
CONSTRAINT `fk_keyword_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
CONSTRAINT `fk_keyword_user2` FOREIGN KEY (`updated_user_id`) REFERENCES `user` (`id`)

Chci udělat where na tabulku user. Je mi rozumět?

Pokud se spojovací sloupec jmenuje dle „defaultní konvence“ (user_id) tak where(‚user.name = ?‘) funguje. Potřebuju tam nějak nacpat ten jinak pojmenovaný sloupec.

Editoval o5 (30. 5. 2014 13:32)

David Matějka
Moderator | 6445
+
0
-

@o5: ty mas conventional reflection? discovered reflection by si totiz melo poradit i s 'user.name = ?'. Jeste zkus 'updated_user.name = ?'..

o5
Člen | 416
+
0
-

@matej21: dík, ‚updated_user.name = ?‘ funguje. Mám v tom teď zase zmatek, ty dvojtečky se používaly dříve, nevíš?

Editoval o5 (30. 5. 2014 13:48)

David Matějka
Moderator | 6445
+
0
-

dvojtecky se pouzivaly a pouzivaji jen pro „has many“