diff --git a/src/Database/Conventions/DiscoveredConventions.php b/src/Database/Conventions/DiscoveredConventions.php index 1f47d5d1f..0e71651bb 100644 --- a/src/Database/Conventions/DiscoveredConventions.php +++ b/src/Database/Conventions/DiscoveredConventions.php @@ -30,6 +30,11 @@ public function getPrimary($table) { return $this->structure->getPrimaryKey($table); } + + public function getForeign($table, $key) + { + return $this->structure->getForeignKey($table, $key); + } public function getHasManyReference($nsTable, $key) @@ -86,7 +91,7 @@ public function getBelongsToReference($table, $key) $tableColumns = $this->structure->getBelongsToReference($table); foreach ($tableColumns as $column => $targetTable) { - if (stripos($column, $key) !== FALSE) { + if (stripos($column, $key) !== FALSE || stripos($targetTable, $key) !== FALSE) { //also check if any reference exists return [$targetTable, $column]; } } diff --git a/src/Database/Structure.php b/src/Database/Structure.php index 48f40e86d..839087af2 100644 --- a/src/Database/Structure.php +++ b/src/Database/Structure.php @@ -62,8 +62,22 @@ public function getPrimaryKey($table) return $this->structure['primary'][$table]; } + + + //Get foreign keys by table and return local column name in referenced table. + //@TODO cache getForeignKeys($table) call + public function getForeignKey($table, $column) + { + foreach($this->connection->getSupplementalDriver()->getForeignKeys($table) as $row) { + if($row["local"] == $column) { + return $row["foreign"]; + } + } + return NULL; + } + public function getPrimaryKeySequence($table) { $this->needStructure(); diff --git a/src/Database/Table/Selection.php b/src/Database/Table/Selection.php index 733b6ec5b..4bc4e3fee 100644 --- a/src/Database/Table/Selection.php +++ b/src/Database/Table/Selection.php @@ -869,13 +869,19 @@ public function getReferencedTable(ActiveRow $row, $table, $column = NULL) if ($cacheKeys) { $selection = $this->createSelectionInstance($table); - $selection->where($selection->getPrimary(), array_keys($cacheKeys)); + + //search for foreign key column name which is referenced from activeRow parent table to table from which is selection made + $foreign = $this->conventions->getForeign($row->getTable()->getName(), $column); + $primary = $foreign == NULL ? $selection->getPrimary() : $foreign; + + $selection->where($primary, array_keys($cacheKeys)); } else { - $selection = []; + $selection = NULL; } } - - return isset($selection[$checkPrimaryKey]) ? $selection[$checkPrimaryKey] : NULL; + + return $selection; + //return isset($selection[$checkPrimaryKey]) ? $selection[$checkPrimaryKey] : NULL; } diff --git a/src/Database/Table/SqlBuilder.php b/src/Database/Table/SqlBuilder.php index 738d9049f..449771564 100644 --- a/src/Database/Table/SqlBuilder.php +++ b/src/Database/Table/SqlBuilder.php @@ -480,7 +480,8 @@ public function parseJoinsCb(& $joins, $match) throw new Nette\InvalidArgumentException("No reference found for \${$parent}->{$keyMatch['key']}."); } list($table, $column) = $belongsTo; - $primary = $this->conventions->getPrimary($table); + $foreign = $this->conventions->getForeign($parent, $column); //check for foreign key instead primary key in referenced table + $primary = $foreign == NULL ? $this->conventions->getPrimary($table) : $foreign; } $tableAlias = $keyMatch['key'] ?: preg_replace('#^(.*\.)?(.*)$#', '$2', $table);