One to Many¶
An one to many bi-directional relationship between entities can be defined as follows.
Entity Structure¶
app/Domain/Entities/Mother.php¶
<?php declare(strict_types=1);
namespace App\Domain\Entities;
use Dms\Core\Model\EntityCollection;
use Dms\Core\Model\Object\ClassDefinition;
use Dms\Core\Model\Object\Entity;
class Mother extends Entity
{
const NAME = 'name';
const CHILDREN = 'children';
/**
* @var string
*/
public $name;
/**
* @var EntityCollection|Child[]
*/
public $children;
/**
* Parent constructor.
*/
public function __construct()
{
parent::__construct();
$this->children = Child::collection();
}
/**
* Defines the structure of this entity.
*
* @param ClassDefinition $class
*/
protected function defineEntity(ClassDefinition $class)
{
$class->property($this->name)->asString();
$class->property($this->children)->asType(Child::collectionType());
}
}
app/Domain/Entities/Child.php¶
<?php declare(strict_types=1);
namespace App\Domain\Entities;
use Dms\Core\Model\Object\ClassDefinition;
use Dms\Core\Model\Object\Entity;
class Child extends Entity
{
const NAME = 'name';
const MOTHER = 'mother';
/**
* @var string
*/
public $name;
/**
* @var Mother
*/
public $mother;
/**
* Child constructor.
*
* @param string $name
* @param Mother $mother
*/
public function __construct($name, Mother $mother)
{
parent::__construct();
$this->name = $name;
$this->mother = $mother;
}
/**
* Defines the structure of this entity.
*
* @param ClassDefinition $class
*/
protected function defineEntity(ClassDefinition $class)
{
$class->property($this->name)->asString();
$class->property($this->mother)->asObject(Mother::class);
}
}
Mapper Configuration¶
app/Infrastructure/Persistence/MotherMapper.php¶
<?php declare(strict_types = 1);
namespace App\Infrastructure\Persistence;
use Dms\Core\Persistence\Db\Mapping\Definition\MapperDefinition;
use Dms\Core\Persistence\Db\Mapping\EntityMapper;
use App\Domain\Entities\Mother;
use App\Domain\Entities\Child;
/**
* The App\Domain\Entities\Mother entity mapper.
*/
class MotherMapper extends EntityMapper
{
/**
* Defines the entity mapper
*
* @param MapperDefinition $map
*
* @return void
*/
protected function define(MapperDefinition $map)
{
$map->type(Mother::class);
$map->toTable('mothers');
$map->idToPrimaryKey('id');
$map->property(Mother::NAME)->to('name')->asVarchar(255);
$map->relation(Mother::CHILDREN)
->to(Child::class)
->toMany()
->identifying()
->withBidirectionalRelation(Child::MOTHER)
->withParentIdAs('mother_id');
}
}
app/Infrastructure/Persistence/ChildMapper.php¶
<?php declare(strict_types = 1);
namespace App\Infrastructure\Persistence;
use Dms\Core\Persistence\Db\Mapping\Definition\MapperDefinition;
use Dms\Core\Persistence\Db\Mapping\EntityMapper;
use App\Domain\Entities\Child;
use App\Domain\Entities\Mother;
/**
* The App\Domain\Entities\Child entity mapper.
*/
class ChildMapper extends EntityMapper
{
/**
* Defines the entity mapper
*
* @param MapperDefinition $map
*
* @return void
*/
protected function define(MapperDefinition $map)
{
$map->type(Child::class);
$map->toTable('children');
$map->idToPrimaryKey('id');
$map->property(Child::NAME)->to('name')->asVarchar(255);
$map->column('mother_id')->asUnsignedInt();
$map->relation(Child::MOTHER)
->to(Mother::class)
->manyToOne()
->withBidirectionalRelation(Mother::CHILDREN)
->withRelatedIdAs('mother_id');
}
}
Module Configuration¶
app/Cms/Modules/MotherModule.php¶
<?php declare(strict_types = 1);
namespace App\Cms\Modules;
use Dms\Core\Auth\IAuthSystem;
use Dms\Core\Common\Crud\CrudModule;
use Dms\Core\Common\Crud\Definition\CrudModuleDefinition;
use Dms\Core\Common\Crud\Definition\Form\CrudFormDefinition;
use Dms\Core\Common\Crud\Definition\Table\SummaryTableDefinition;
use App\Domain\Services\Persistence\IMotherRepository;
use App\Domain\Entities\Mother;
use Dms\Common\Structure\Field;
use App\Domain\Services\Persistence\IChildRepository;
use App\Domain\Entities\Child;
/**
* The mother module.
*/
class MotherModule extends CrudModule
{
/**
* @var IChildRepository
*/
protected $childRepository;
public function __construct(IMotherRepository $dataSource, IAuthSystem $authSystem, IChildRepository $childRepository)
{
$this->childRepository = $childRepository;
parent::__construct($dataSource, $authSystem);
}
/**
* Defines the structure of this module.
*
* @param CrudModuleDefinition $module
*/
protected function defineCrudModule(CrudModuleDefinition $module)
{
$module->name('mother');
$module->labelObjects()->fromProperty(Mother::NAME);
$module->crudForm(function (CrudFormDefinition $form) {
$form->section('Details', [
$form->field(
Field::create('name', 'Name')->string()->required()
)->bindToProperty(Mother::NAME),
//
$form->field(
Field::create('children', 'Children')
->entitiesFrom($this->childRepository)
->labelledBy(Child::NAME)
->mapToCollection(Child::collectionType())
// Add this line if you want to load the
// options asynchronously via autocomplete
->searchableBy(Child::NAME)
)->bindToProperty(Mother::CHILDREN),
//
]);
});
$module->removeAction()->deleteFromDataSource();
$module->summaryTable(function (SummaryTableDefinition $table) {
$table->mapProperty(Mother::NAME)->to(Field::create('name', 'Name')->string()->required());
$table->view('all', 'All')
->loadAll()
->asDefault();
});
}
}
app/Cms/Modules/ChildModule.php¶
<?php declare(strict_types = 1);
namespace App\Cms\Modules;
use Dms\Core\Auth\IAuthSystem;
use Dms\Core\Common\Crud\CrudModule;
use Dms\Core\Common\Crud\Definition\CrudModuleDefinition;
use Dms\Core\Common\Crud\Definition\Form\CrudFormDefinition;
use Dms\Core\Common\Crud\Definition\Table\SummaryTableDefinition;
use App\Domain\Services\Persistence\IChildRepository;
use App\Domain\Entities\Child;
use Dms\Common\Structure\Field;
use App\Domain\Services\Persistence\IMotherRepository;
use App\Domain\Entities\Mother;
/**
* The child module.
*/
class ChildModule extends CrudModule
{
/**
* @var IMotherRepository
*/
protected $motherRepository;
public function __construct(IChildRepository $dataSource, IAuthSystem $authSystem, IMotherRepository $motherRepository)
{
$this->motherRepository = $motherRepository;
parent::__construct($dataSource, $authSystem);
}
/**
* Defines the structure of this module.
*
* @param CrudModuleDefinition $module
*/
protected function defineCrudModule(CrudModuleDefinition $module)
{
$module->name('child');
$module->labelObjects()->fromProperty(Child::NAME);
$module->crudForm(function (CrudFormDefinition $form) {
$form->section('Details', [
$form->field(
Field::create('name', 'Name')->string()->required()
)->bindToProperty(Child::NAME),
//
$form->field(
Field::create('mother', 'Mother')
->entityFrom($this->motherRepository)
->required()
->labelledBy(Mother::NAME)
)->bindToProperty(Child::MOTHER),
]);
});
$module->removeAction()->deleteFromDataSource();
$module->summaryTable(function (SummaryTableDefinition $table) {
$table->mapProperty(Child::NAME)->to(Field::create('name', 'Name')->string()->required());
$table->view('all', 'All')
->loadAll()
->asDefault();
});
}
}