Database\Table: Simple mapping
- OndrejSlamecka
- Member | 41
Every row Database\Table outputs is an ActiveRow created in Selection::createRow. Overloading createRow is complicated because that would require extending class Selection and it is hardcoded into SelectionFactory which is hardcoded into Nette extension of DI container builder.
I therefore propose that Nette would allow the following configuration:
database:
mapping: App\Entity\*
This mapping
property would be injected into Selection. In
createRow the *
would be replaced with table name, it would be
verified that class_exist
and finally a new instance (object) of
that class would be created and returned. If mapping
was unset/null
or class_exist
would fail then it would fallback to ActiveRow (⇒
no BC break!).
Let me know what do you think.
(You may ask: Why use custom entities? Imagine object Product with properties Price and Vat. You want to get price with VAT at 20 places in the template. Simple Product::getPriceWithVat() would make it simple and prevent code repeating.)
Last edited by OndrejSlamecka (2013-08-30 19:17)
- jiri.pudil
- Nette Blogger | 1029
I believe composition is a much better approach here, as NDb is not an ORM. Something like:
class Product extends Nette\Object
{
private $row;
public function __construct(ActiveRow $row)
{
$this->row = $row;
}
public function getPriceWithVat()
{
// e.g.
return $this->row->price * (1 + $this->row->vat);
}
}
- OndrejSlamecka
- Member | 41
With the code you showed you would have to create an instance of that class on every result from Database\Table.
- OndrejSlamecka
- Member | 41
Proof of concept (mapping is simpler than described above just <tableName>: <className> array): https://github.com/…210d714dabe0 (entity class should be required to extend ActiveRow)
EDIT: A better implementation occured to me, which does not implement mapper but adds RowFactory (a service which anyone can replace with their own). PoC here: https://github.com/…4fb5f69220a8
Last edited by OndrejSlamecka (2014-09-20 10:42)