Nextras\ORM a views – jak na to?
- chikeet
- Člen | 160
Zdravím,
zkouším použít pro jeden datagrid v aplikaci view místo tabulky
(s vlastní entitou nad tím view, pochopitelně) a nemůžu se dostat
přes tohle:
Storage 'places_view' has not defined any primary key.
Na tom view primární klíč nenastavím, neb to MySQL podle všeho neumožňuje. View si bere primární klíč ze své základní tabulky, ale vypadá to, že to nestačí.
Dá se to nějak rozumně obejít? Nastavit nějak třeba v mapperu, nebo něco na ten způsob?
V mapperu mám aktuálně definovaný pouze název view:
class PlaceViewsMapper extends BaseMapper
{
function getTableName() {
return "places_view";
}
}
BaseMapper:
use Nextras\Orm\Mapper\Dbal\QueryBuilderHelper;
use Nextras\Orm\Mapper\Mapper;
abstract class BaseMapper extends Mapper
{
public function getAlias()
{
return QueryBuilderHelper::getAlias($this->getTableName());
}
}
PlaceView:
/**
* @property int $id {primary}
* ...
*/
- Jan Tvrdík
- Nette guru | 2595
@chikeet Dohledal jsem tohle starší vlákno https://gist.github.com/…47bb1632d0f0#…
- chikeet
- Člen | 160
Jan Tvrdík napsal(a):
@chikeet Dohledal jsem tohle starší vlákno https://gist.github.com/…47bb1632d0f0#…
Díky moc, pomohlo.
Jen ještě nevím, jestli nějak můžu přimět ORM, aby používalo cizí
klíče z původní tabulky places. Všechny sloupce, kterých se to týká,
jsou do view natáhnuté z places (např. region_id), v places jsou na ně
nastavené cizí klíče (a bez problémů fungují), ale ve view jsou všechny
navázané entity nullové (např. ten region). Svou custom StorageReflection
mám vytvořenou tak, že extenduju UnderscoredStorageReflection
,
ale hádám, že tam asi problém nebude vzhledem k tomu, že se tam jen
překládájí názvy sloupců na properties.
- Jan Tvrdík
- Nette guru | 2595
@chikeet Můžeš zkusit pro to view vrátit reflection té tabulky? Tj. dát jako druhý parametr konstruktoru místo názvu view název té tabulky, které té view odpovídá?
- chikeet
- Člen | 160
Jan Tvrdík napsal(a):
@chikeet Můžeš zkusit pro to view vrátit reflection té tabulky? Tj. dát jako druhý parametr konstruktoru místo názvu view název té tabulky, které té view odpovídá?
Paráda, funguje – díky moc!
Kdyby se to někomu hodilo, tak…
Mapper:
class PlaceViewsMapper extends BaseMapper
{
function getTableName() {
return "places_view";
}
protected function createStorageReflection()
{
return new ViewReflection(
$this->connection,
'places', // nazev tabulky misto $this->getTableName()
$this->getRepository()->getEntityMetadata()->getPrimaryKey(),
$this->cache
);
}
}
StorageReflection:
use Nextras\Orm\Mapper\Dbal\StorageReflection\UnderscoredStorageReflection;
class ViewReflection extends UnderscoredStorageReflection
{
public function getStoragePrimaryKey()
{
return ['id'];
}
protected function getDefaultMappings()
{
return [];
}
protected function getDefaultModifiers()
{
return [];
}
}
Edit: tak to vypadá, že postup s nastavením tabulky natvrdo zmate ORM tak, že se snaží view používat i tam, kde má být použita tabulka (původní entita Places). Takže zatím nevyřešeno.
Editoval chikeet (30. 5. 2017 22:03)
- chikeet
- Člen | 160
@hrach Zkusím, zatím mi to nefunguje podle očekávání (viz edit v předchozím příspěvku). Popravdě nemám fungování Nextras\ORM nastudováno moc nad rámec základní práce, takže se v tom zatím blbě orientuju a dost možná dělám chyby z neznalosti (LeanMapper i Doctrine mi přišly srozumitelnější, ale třeba to chce jen pořádně pročíst docku).
- chikeet
- Člen | 160
@hrach Tak nakonec stačilo použít ViewReflection
s přepsanou metodou getStoragePrimaryKey
, jinak to padalo právě
na tom chybějícím primary key (při použití přímo
UnderscoredStorageReflection
).
Foreign key properties vyřešilo přepsání table name na
places
(původní tabulka k places_view
).
Aby to nerozhazovalo vztahy jinde v aplikaci, bylo třeba použít
u navázaných entit v PlaceView oneSided=true
.