I'll explain what I'm trying to do.
I have the following entities, Dealers Brands and Types.
1 Dealer can have many brands associated and each relation will have one type associated as well, that's why is a manyToMany relationship with an intermediate table.
I want to create a Form to Add dealers to our system and when doing so they can choose which brands are associated (there are few brands so we want to display them as checkboxes) and of what type, but trying to show this form with the brands is been tricky until now.
Brand Entity
/**
* Brand
*
* @ORM\Table()
* @ORM\Entity
*/
class Brand
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* @ORM\ManyToMany(targetEntity="TypeBrand")
* @ORM\JoinTable(name="brand_type",
* joinColumns={@ORM\JoinColumn(name="brand_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="type_id", referencedColumnName="id")}
* )
*/
private $type;
/**
* @ORM\OneToMany(targetEntity="DealerBrand", mappedBy="brand")
*/
private $dealerBrand;
public function __construct()
{
$this->type = new ArrayCollection();
$this->dealerBrand = new ArrayCollection();
}
public function __toString()
{
return $this->getName();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Brand
*/
public function setName($name)
{
$this->name = $name;
$this->setSlug($name);
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
public function addType(TypeBrand $type)
{
$this->type[] = $type;
}
public function getType()
{
return $this->type;
}
public function addDealerBrand($dealerBrand)
{
$this->dealerBrand[] = $dealerBrand;
}
public function getDealerBrand()
{
return $this->dealerBrand;
}
}
Dealer Entity
/**
* Dealer
*
* @ORM\Table("dealer")
* @ORM\Entity(repositoryClass="Project\DealersBundle\Entity\Repository\DealerRepository")
* @Gedmo\Loggable
*/
class Dealer
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=true)
* @Assert\NotBlank()
* @Assert\Length(min = "10")
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="DealerBrand", mappedBy="dealer")
*
*/
private $dealerBrand;
public function __construct()
{
$this->dealerBrand = new ArrayCollection();
}
public function __toString()
{
return $this->getName();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* @param string $name
* @return Dealer
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
public function addDealerBrand($dealerBrand)
{
$this->dealerBrand[] = $dealerBrand;
}
public function getDealerBrand()
{
return $this->dealerBrand;
}
}
DealerBrand Entity
/**
* DealerBrand
*
* @ORM\Table("dealer_brand")
* @ORM\Entity
*/
class DealerBrand
{
/**
* @var integer
*
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Dealer", inversedBy="dealerBrand")
*/
private $dealer;
/**
* @var integer
*
* @ORM\Id
* @ORM\ManyToOne(targetEntity="Brand", inversedBy="dealerBrand")
*/
private $brand;
/**
* Set dealer
*
* @param integer $dealer
* @return DealerBrand
*/
public function setDealer($dealer)
{
$this->dealer = $dealer;
return $this;
}
/**
* Get dealer
*
* @return integer
*/
public function getDealer()
{
return $this->dealer;
}
/**
* Set brand
*
* @param integer $brand
* @return DealerBrand
*/
public function setBrand($brand)
{
$this->brand = $brand;
return $this;
}
/**
* Get brand
*
* @return integer
*/
public function getBrand()
{
return $this->brand;
}
}
Now this are my formtypes
DealerBrandType
class DealerBrandType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('brand', 'entity', array(
'class' => 'Project\DealersBundle\Entity\Brand',
'property' => 'name',
'multiple' => true,
'expanded' => true,
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Project\DealersBundle\Entity\DealerBrand'
)
);
}
public function getName()
{
return 'DealerBrand';
}
}
DealerType
class DealerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('dealerBrand', 'collection', array(
'type' => new DealerBrandType(),
'allow_add' => true,
'allow_delete' => true,
))
->add('Save', 'submit');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Project\DealersBundle\Entity\Dealer'
)
);
}
public function getName()
{
return 'dealerType';
}
}
And this is my controller
public function addAction()
{
$dealer = new Dealer();
$form = $this->createForm(new DealerType(), $dealer);
$form->handleRequest($this->getRequest());
if ($form->isValid()) {
$this->getDoctrine()->getManager()->persist($dealer);
$this->getDoctrine()->getManager()->flush();
return $this->redirect($this->generateUrl('dealers_list'));
}
return $this->render(
'ProjectDealersBundle:Dealers:AddDealer.html.twig',
array(
'form' => $form->createView()
)
);
}
If this is not the correct approach please tell me, tell me also if you see bad code, that way I can improve
* EDIT *
This is the result i need
http://tinypic.com/r/24pkzdc/8
You can see there the brands and so .. so the idea is that when saving the Dealer you also save the association with the brands
* END EDIT *
Thank you!