Nette database: GroupedSelection :: group – potencionální bug

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

Ahoj,

na projektu jsme narazili na dost „unfriendly“ chování nette database v následující replikaci

article[id]
{1}
{2}

comment[id, article_id, some_col]
{1, 1, 1}
{2, 1, 2}
{3, 2, 1}
{4, 2, 2}
{5, 2, 2}

$articles = $db->table('article');
foreach($articles as $article){
	foreach($article->related('comments')->group('some_col') as $comment){
		echo $comment->id . '-' . $comment->some_col;
	}
}

//output
//1 - 1
//2 - 2

//expected
//1 - 1
//2 - 2
//3 - 1
//4 - 2

Data se totiž tahají v jedné query (WHERE IN) a group se provede nad celým výsledkem.

Chtělo by to do Nette\Database\Table\GroupedSelection přepsat group na něco jako

	public function group($columns)
	{
		$this->emptyResultSet();
		$columns .= ", $this->name.$this->column";
		call_user_func_array(array($this->sqlBuilder, 'setGroup'), [$columns]);
		return $this;
	}

Nevím zda je to bug nebo featura, ale rozhodně je to dost nevypočitatelné chování, které nás relativně dost potrápilo.

petr.jirous
Člen | 128
+
0
-

No podle mě je output docela expected ;) ten group funguje tak jak má…

winner21
Člen | 5
+
0
-

Já tedy vždy
ActiveRow::related rozuměl jako ekvivalent (zkratku) k

$article->related('comments');
//zkratka pro
$db->table('comments')->where('article_id', $article->id);

A grouped selection pouze jako optimalizaci, aby se nevytvářel dotaz pro každý článek.

Takto se například GroupedSelection::sort vztahuje na konkrétní „active“ kolekci GroupedSelection a group se vztahuje na celý výsledek..

winner21
Člen | 5
+
0
-

V podstatě to znamená, že pro následující dva snippety kódu budou mít jiný output.

$articles = $db->table('articles')->where('id', [1, 2]);
foreach($articles as $article){
    foreach($article->related('comments')->group('some_col') as $comment){
        echo $comment->id . '-' . $comment->some_col;
    }
}

//
$articles = [
	$db->table('articles')->where('id', 1)->fetch(),
	$db->table('articles')->where('id', 2)->fetch()
];
foreach($articles as $article){
    foreach($article->related('comments')->group('some_col') as $comment){
        echo $comment->id . '-' . $comment->some_col;
    }
}

A toto jestli je „expected“, tak jsem rád, že na nové projekty již používáme Doctrine2..

David Matějka
Moderator | 6445
+
0
-

na nové projekty již používáme Doctrine2..

+1 :)

Jinak bych to videl na bug, muzes poslat PR?

winner21
Člen | 5
+
0
-

Ok hodil jsem ho tam. Snad to má všecky náležitosti. Kód ndb ale moc dobře neznám, tak snad to nerozbijí něco jiného.