Reputation: 3003
I have the following DB structure.
Pge\IncidenciasBundle\Entity\Cliente:
type: entity
table: cliente
repositoryClass: Pge\IncidenciasBundle\Entity\ClienteRepository
id:
id:
type: integer
generator:
strategy: IDENTITY
fields:
nombre:
type: string
length: 250
fixed: false
nullable: true
manyToMany:
servicios:
targetEntity: Servicio
cascade: [persist]
lifecycleCallbacks: { }
Pge\IncidenciasBundle\Entity\Servicio:
type: entity
table: servicio
id:
id:
type: integer
generator:
strategy: IDENTITY
fields:
nombre:
type: string
length: 250
fixed: false
nullable: true
lifecycleCallbacks: { }
Right now, there's a DB table called cliente_servicio
that keeps the relations between this two entities, some data for example:
cliente_id servicio_id
1 1
1 4
1 8
2 1
3 3
3 7
The forms are totally working right now to manage this relation. But now, I need another function.
I need to create a new form/structure/whatever you tell me to set two extra fields per row: status
and comment
and date
so the final DB output will be this:
cliente_id servicio_id date status comment
1 1 2013-09-19 ok null
1 4 2013-09-19 ko Needs to clear
1 8 2013-09-19 ok null
2 1 2013-09-19 ko Packets lost (fix firewall)
3 3 2013-09-19 ko Out of service (see ticket T9388)
3 7 2013-09-19 ok null
The point is to call route localhost/whatever/{id}/{date}
where {id}
is cliente_id
(can be the client name if necessary field nombre
of cliente
entity) and {date} is date, on this page index, it will display the recorded data (the data I want to create but I don't know how) for a given date for selected cliente_id
.
On the new
action, the form will display a field for estado
, comment
and date
for each servicio_id
assigned to {id}
(cliente_id
)
I think it is easy to make if you know Symfony2, but I'm totally lost... With simple PHP (no frameworks) I managed to handle this situation and it's working, but I don't know how with Symfony2.
Additional info:
Table cliente_servicio
which handles the manyToMany
relationship is not mapped on Symfony2, because it was auto-generated with doctrine:schema:update --force
it can't be mapped because its lack of id primary key (it only has cliente_id
and servicio_id
)
UPDATE
Okay, doing Doctrine2: Best way to handle many-to-many with extra columns in reference table so now I have m:1 and 1:m relations with an intermediate entity for cliente
and servicio
called clienteservicio
I've found that I'm not able to assign servicio
to cliente
from cliente
form.
Neither from servicio
form.
I can from ClienteServicio
newly created entity, the "intermediate" one. BUT, I cannot select multiple servicio
for one cliente
, like I was able before.
Also, the point was to have in one single form, X rows with estado
, comentario
and date
fields where X = number of servicio
assigned to given cliente
<?php
namespace Pge\IncidenciasBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Cliente
*
* @ORM\Table(name="cliente")
* @ORM\Entity(repositoryClass="Pge\IncidenciasBundle\Entity\ClienteRepository")
*/
class Cliente
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nombre", type="string", length=250, nullable=true)
*/
private $nombre;
/**
* @var \Doctrine\Common\Collections\Collection
* @ORM\OneToMany(targetEntity="ClienteServicio", mappedBy="cliente")
*/
private $servicio;
public function __toString()
{
return $this->nombre;
}
/**
* Constructor
*/
public function __construct()
{
$this->servicio = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nombre
*
* @param string $nombre
* @return Cliente
*/
public function setNombre($nombre)
{
$this->nombre = $nombre;
return $this;
}
/**
* Get nombre
*
* @return string
*/
public function getNombre()
{
return $this->nombre;
}
/**
* Add servicio
*
* @param \Pge\IncidenciasBundle\Entity\ClienteServicio $servicio
* @return Cliente
*/
public function addServicio(\Pge\IncidenciasBundle\Entity\ClienteServicio $servicio)
{
$this->servicio[] = $servicio;
return $this;
}
/**
* Remove servicio
*
* @param \Pge\IncidenciasBundle\Entity\ClienteServicio $servicio
*/
public function removeServicio(\Pge\IncidenciasBundle\Entity\ClienteServicio $servicio)
{
$this->servicio->removeElement($servicio);
}
/**
* Get servicio
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getServicio()
{
return $this->servicio;
}
}
<?php
namespace Pge\IncidenciasBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Servicio
*
* @ORM\Table(name="servicio")
* @ORM\Entity
*/
class Servicio
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="nombre", type="string", length=250, nullable=true)
*/
private $nombre;
/*
*
* @ORM\OneToMany(targetEntity="ClienteServicio", mappedBy="servicio")
*/
private $cliente;
public function __toString()
{
return $this->nombre;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set nombre
*
* @param string $nombre
* @return Servicio
*/
public function setNombre($nombre)
{
$this->nombre = $nombre;
return $this;
}
/**
* Get nombre
*
* @return string
*/
public function getNombre()
{
return $this->nombre;
}
}
<?php
namespace Pge\IncidenciasBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* ClienteServicio
*
* @ORM\Table(name="cliente_servicio")
* @ORM\Entity
*/
class ClienteServicio
{
/**
* @var integer
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="estado", type="string", length=255, nullable=false)
*/
private $estado;
/**
* @var string
*
* @ORM\Column(name="comentario", type="string", length=255, nullable=false)
*/
private $comentario;
/**
* @var \DateTime
*
* @ORM\Column(name="fecha", type="date", nullable=false)
*/
private $fecha;
/**
* @var \Pge\IncidenciasBundle\Entity\Servicio
*
* @ORM\ManyToOne(targetEntity="Servicio", inversedBy="cliente")
*/
private $servicio;
/**
* @var \Pge\IncidenciasBundle\Entity\Id
*
* @ORM\ManyToOne(targetEntity="Cliente", inversedBy="servicio")
*/
private $cliente;
/**
* Set id
*
* @param integer $id
* @return ClienteServicio
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set estado
*
* @param string $estado
* @return ClienteServicio
*/
public function setEstado($estado)
{
$this->estado = $estado;
return $this;
}
/**
* Get estado
*
* @return string
*/
public function getEstado()
{
return $this->estado;
}
/**
* Set comentario
*
* @param string $comentario
* @return ClienteServicio
*/
public function setComentario($comentario)
{
$this->comentario = $comentario;
return $this;
}
/**
* Get comentario
*
* @return string
*/
public function getComentario()
{
return $this->comentario;
}
/**
* Set fecha
*
* @param \DateTime $fecha
* @return ClienteServicio
*/
public function setFecha($fecha)
{
$this->fecha = $fecha;
return $this;
}
/**
* Get fecha
*
* @return \DateTime
*/
public function getFecha()
{
return $this->fecha;
}
/**
* Set servicio
*
* @param \Pge\IncidenciasBundle\Entity\Servicio $servicio
* @return ClienteServicio
*/
public function setServicio(\Pge\IncidenciasBundle\Entity\Servicio $servicio = null)
{
$this->servicio = $servicio;
return $this;
}
/**
* Get servicio
*
* @return \Pge\IncidenciasBundle\Entity\Servicio
*/
public function getServicio()
{
return $this->servicio;
}
/**
* Set cliente
*
* @param \Pge\IncidenciasBundle\Entity\Cliente $cliente
* @return ClienteServicio
*/
public function setCliente(\Pge\IncidenciasBundle\Entity\Cliente $cliente = null)
{
$this->cliente = $cliente;
return $this;
}
/**
* Get cliente
*
* @return \Pge\IncidenciasBundle\Entity\Cliente
*/
public function getCliente()
{
return $this->cliente;
}
}
As I said, the point is assign servicio
to a cliente
from cliente
form.
Then, from another form, set the extra fields to the servicio
assigned to cliente
(It would be great if I can handle every servicio
for one cliente
in one form containing a row for each servicio
)
The way I'm doing right now, is not the way I want it...
Upvotes: 0
Views: 305
Reputation: 2191
The Answer from the comments is still applicable.
You just need to turn your m:n relation to a m:1 plus 1:n relation that you will end up with 3 Entities instead of 2. And as soon as you have 3 Entities you can also just create a new form for the "intermediate" entity, because it is like every other entity.
UPDATE:
You can still simulate the same thing if you add some logic to your client:
public function addService(Service $service){
$clientService = new ClientService();
$clientService->setClient($this);
$clientService->setService($service);
$this->clientService->add($clientService);
}
You can do some similar simulations with getService();
Alternative is that you only need to adopt your Form and have multiple clientservicio on your client form but then on each clientservicio form only one service. This should still work.
Upvotes: 2