Nette Database – jak udělat vazbu, když není možné dodržet konvenci
- semtex.989
- Člen | 75
Narazil jsem na zajímavý problém, kdy nemohu Nette\Database použít, pokud potřebuji dvě vazby na druhou tabulku. Vše nastíním na ukázce databáze:
Tabulka tasks
id int(11) Auto Increment
creator_id int(11)
worker_id int(11)
state_id int(11)
priority_id int(11)
title varchar(128)
text text
date_created datetime
last_edited timestamp [CURRENT_TIMESTAMP]
Tabulka users
id int(11) Auto Increment
username varchar(40)
realname varchar(40)
password varchar(40)
email varchar(40)
supervisor int(1) [0]
last_state_change datetime
Protože v tabulce potřebuju mít vazbu jednak na toho kdo úkol vytvořil (creator_id) ale i pro koho je úukol určen (worker_id). Takže nemohu použít jeden sloupec user_id.
Dá se to nějak řešit?
Taky jsem nenašel, jestli se dá vnutit nějak konvence jako u NotORM… Je to možné?
- petr.pavel
- Člen | 535
Ahoj, řešením je definovat vlastního potomka NConnection a přes něj použít vlastní definici NDatabaseReflection. Přikládám, jak jsem to řešil já, když jsem potřeboval použít prefixované tabulky (bm_neco) a creator_id/evaluator_id byly moje cizí klíče – odkazy do tabulky bm_administrator. Taky je v tom, jak jsem řešil přístup ke view.
Aby se použilo moje MyNConnection, v config.neon jsem měl:
services:
database:
class: MyNConnection
arguments: ["mysql:host=.....]
app/database/MyConnection.php
<?php
class MyNConnection extends NConnection {
public function __construct($dsn, $username = NULL, $password = NULL, array $options = NULL) {
parent::__construct($dsn, $username, $password, $options);
$this->databaseReflection = new MyDatabaseReflection();
}
}
class MyDatabaseReflection extends NDatabaseReflection {
public function __construct() {
parent::__construct('id', '%s_id', 'bm_%s');
}
function getReferencedTable($name, $table) {
if ($name == "creator" || $name == "evaluator") {
return "bm_administrator";
}
return parent::getReferencedTable($name, $table);
}
public function getPrimary($table) {
if ($table == "bm_view_task") {
return "nonsense"; // there is no primary key; 'disable' the primary key feature to make NTableSelection->exec() work
}
if ($table == "bm_email_template") {
return "name";
}
return parent::getPrimary($table);
}
public function getReferencedColumn($name, $table) {
if ($name == "creator" || $name == "evaluator") {
return "${name}_id";
}
return parent::getReferencedColumn($name, $table);
}
public function getPrefixedTable($table) {
return parent::getPrefixedTable($table);
}
}
?>
Podotýkám, že moje řešení se nezabývá množným číslem v názvu tabulky. Je s tím taková práce, že jsem radši změnil víru a používám teď pro tabulky jednotné číslo: user místo users. Ušetříš si práci s chuťovkami jako property/properties atp.
Editoval petr.pavel (11. 11. 2011 0:11)