php - easycorp - symfony admin
El ID de padre de la entidad no se guarda en una relaciĆ³n OneToMany en SonataAdmin (2)
Estoy usando SonataAdmin (y Symfony2) para administrar mis entidades. Tengo una relación OneToMany entre un paso y muchas tareas. Como un Paso puede contener muchas Tareas, cuando creo un Paso, quiero poder crear muchas Tareas y quiero que esas tareas estén vinculadas a este Paso. Para hacerlo, creé todas las clases de administración adecuadas (una para Tarea y otra para Paso).
Esto es lo que hago que causa mi problema. Cuando intento crear un Paso, puedo crear las tareas e incluso reordenarlas, lo que es genial y todo lo hace SonataAdminBundle automáticamente. Cuando hago clic en guardar, todo se guarda en la base de datos, excepto que en la base de datos, el ID del paso no se establece en la fila de la Tarea. Por lo tanto, las tareas no están vinculadas al Paso ...
Aquí está la clase de administración de mi Paso:
<?php
// src/Acme/DemoBundle/Admin/PostAdmin.php
namespace IMA/ProcessManagementBundle/Admin;
use Sonata/AdminBundle/Admin/Admin;
use Sonata/AdminBundle/Datagrid/ListMapper;
use Sonata/AdminBundle/Datagrid/DatagridMapper;
use Sonata/AdminBundle/Form/FormMapper;
class StepAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add(''name'', ''text'', array(''label'' => ''Nom de l/'étape''))
->add(''tasks'', ''sonata_type_collection'', array(), array(
''edit'' => ''inline'',
''inline'' => ''table'',
''sortable'' => ''positionNumber''
))
->add(''positionNumber'', ''integer'', array(''label'' => ''Position''))
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add(''name'')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier(''name'')
->add(''slug'')
;
}
}
Aquí también está mi clase de administración de tareas:
<?php
// src/Acme/DemoBundle/Admin/PostAdmin.php
namespace IMA/ProcessManagementBundle/Admin;
use Sonata/AdminBundle/Admin/Admin;
use Sonata/AdminBundle/Datagrid/ListMapper;
use Sonata/AdminBundle/Datagrid/DatagridMapper;
use Sonata/AdminBundle/Form/FormMapper;
class TaskAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add(''name'', ''text'', array(''label'' => ''Tâche''))
->add(''positionNumber'', ''integer'', array(''label'' => ''Position''))
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add(''name'')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier(''name'')
->add(''slug'')
;
}
}
Además, aquí están la descripción de mis entidades
IMA/ProcessManagementBundle/Entity/Step:
type: entity
table: null
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
name:
type: string
length: 255
positionNumber:
type: integer
oneToMany:
tasks:
targetEntity: Task
mappedBy: step
cascade: ["persist", "merge"]
lifecycleCallbacks: { }
IMA/ProcessManagementBundle/Entity/Task:
type: entity
table: null
fields:
id:
type: integer
id: true
generator:
strategy: AUTO
name:
type: string
length: 255
positionNumber:
type: integer
manyToOne:
step:
targetEntity: Step
inversedBy: tasks
lifecycleCallbacks: { }
Me pregunto por qué la identificación del Paso no está configurada en la fila de la Tarea ...
En su entidad Step
, debe agregar el método addTask:
class Step
{
//...
public function addTask($tasks)
{
$tasks->setStep($this);
$this->tasks[] = $tasks;
return $this;
}
//...
}
Como no has dado tu Step.php
, debes adaptar este código de manera reproducible.
Debe adjuntar manualmente el paso a las tareas, para hacerlo necesita usar los métodos prePersist y preUpdate en la clase de administración por pasos ...
La razón de esto es que los desarrolladores de SonataAdminBundle dicen que es la preocupación de la doctrina manejar esto y los desarrolladores de Doctrine dicen que es la responsabilidad de los paquetes ... Así que por ahora tenemos que hacerlo por nosotros mismos.
Esta sería su nueva clase stepAdmin:
<?php
namespace IMA/ProcessManagementBundle/Admin;
use Sonata/AdminBundle/Admin/Admin;
use Sonata/AdminBundle/Datagrid/ListMapper;
use Sonata/AdminBundle/Datagrid/DatagridMapper;
use Sonata/AdminBundle/Form/FormMapper;
class StepAdmin extends Admin
{
// Fields to be shown on create/edit forms
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add(''name'', ''text'', array(''label'' => ''Nom de l/'étape''))
->add(''tasks'', ''sonata_type_collection'', array(), array(
''edit'' => ''inline'',
''inline'' => ''table'',
''sortable'' => ''positionNumber''
))
->add(''positionNumber'', ''integer'', array(''label'' => ''Position''))
;
}
// Fields to be shown on filter forms
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add(''name'')
;
}
// Fields to be shown on lists
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier(''name'')
->add(''slug'')
;
}
public function prePersist($object)
{
foreach ($object->getTasks() as $task) {
$task->setStep($object);
}
}
public function preUpdate($object)
{
foreach ($object->getTasks() as $task) {
$task->setStep($object);
}
}
}