I have a dashboard developed on top of Sonata Admin Bundle and I'm having a issue. This is how the method configureFormFields(FormMapper $formMapper)
looks like at CompanyAdmin
admin controller:
protected function configureFormFields(FormMapper $formMapper)
{
$image = $this->getSubject();
$fileFieldOptions = array('required' => false, 'label' => 'Logo');
if ($image && ($webPath = $image->getLogoUrl())) {
$fileFieldOptions['help'] = '<img src="'.$webPath.'" class="admin-preview img-rounded img-responsive"/>';
}
$em = $this->modelManager->getEntityManager('PDI\PDOneBundle\Entity\Brand');
$query = $em->createQueryBuilder('b')
->select('b')
->from('PDOneBundle:Brand', 'b')
->where('b.company IS NULL');
$formMapper
->with('Information', array('class' => 'col-md-6'))
->add('name')
->add('division')
->add('inactive')
->add(
'brands',
'sonata_type_model',
array(
'multiple' => true,
'by_reference' => false,
'query' => $query,
)
)
->end()
->with('Logo', array('class' => 'col-md-6'))
->add('file', 'file', $fileFieldOptions)
->end();
}
The problem here is when I assign a brands
to the company
and try to edit the company after I don't see the brand field filled, why? What I am missing here? Can I get some help?
Below is the example with images. Notice how when I edit the Company I can't see the Brand but when I edit the Brand I can see the Company:
UPDATE
As show on Profiler this is the query executed to get the results on the edit form:
SELECT
t0. NAME AS name_1,
t0.generic_name AS generic_name_2,
t0.logo_url AS logo_url_3,
t0.description AS description_4,
t0.isi_required AS isi_required_5,
t0.isi_text AS isi_text_6,
t0.isi_pdf_url AS isi_pdf_url_7,
t0.pi_required AS pi_required_8,
t0.pi_text AS pi_text_9,
t0.pi_pdf_url AS pi_pdf_url_10,
t0.inactive AS inactive_11,
t0.template_name AS template_name_12,
t0.id AS id_13,
t0.createdAt AS createdAt_14,
t0.updatedAt AS updatedAt_15,
t0.companies_id AS companies_id_16
FROM
brands t0
WHERE
t0.companies_id = 2
And this is the output of that query from DB:
+------------+----------------+------------------------------------------------------------+---------------+----------------+------------+---------------+---------------+-----------+---------------+-------------+------------------+-------+---------------------+---------------------+-----------------+
| name_1 | generic_name_2 | logo_url_3 | description_4 | isi_required_5 | isi_text_6 | isi_pdf_url_7 | pi_required_8 | pi_text_9 | pi_pdf_url_10 | inactive_11 | template_name_12 | id_13 | createdAt_14 | updatedAt_15 | companies_id_16 |
+------------+----------------+------------------------------------------------------------+---------------+----------------+------------+---------------+---------------+-----------+---------------+-------------+------------------+-------+---------------------+---------------------+-----------------+
| Brand Test | | https://someurl.com/no_image_available.png | | 0 | NULL | NULL | 0 | NULL | NULL | 0 | NULL | 2 | 2015-10-22 10:45:14 | 2015-10-26 08:04:53 | 2 |
+------------+----------------+------------------------------------------------------------+---------------+----------------+------------+---------------+---------------+-----------+---------------+-------------+------------------+-------+---------------------+---------------------+-----------------+
So there is a relationship between current company (the record I am editing) and brands, why is not show on the edit form?
UPDATE: Entities
Below are the entities definition for Company
and Brands
:
/**
* @ORM\Entity
* @ORM\Table(name="companies", options={"collate"="utf8_general_ci"})
* @ORM\HasLifecycleCallbacks()
*/
class Company
{
use IdentifierAutogeneratedTrait;
use TimestampableEntity;
use UploadTrait;
/**
* @var string
* @ORM\Column(type="string", length=45)
* @Assert\NotBlank()
*/
protected $name;
/**
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $logo_url = 'https://someurl.com/no_image_available.png';
/**
* @var string
* @ORM\Column(type="string", length=45, nullable=true)
*/
protected $division;
/**
* @var bool
* @ORM\Column(type="boolean")
*/
protected $inactive = false;
/**
* @var Brand
* @ORM\OneToMany(targetEntity="Brand", mappedBy="company", cascade={"persist"})
**/
protected $brands;
public function __construct()
{
$this->brands = new ArrayCollection();
}
...
}
/**
* @ORM\Entity
* @ORM\Table(name="brands")
* @ORM\Entity(repositoryClass="PDI\PDOneBundle\Entity\Repository\BrandRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Brand
{
use IdentifierAutogeneratedTrait;
use TimestampableEntity;
use UploadTrait;
/**
* @var string
* @ORM\Column(type="string", length=45)
* @Assert\NotBlank()
*/
protected $name;
/**
* @var string
* @ORM\Column(type="string", length=45)
* @Assert\NotBlank()
*/
protected $generic_name;
/**
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $logo_url = 'https://someurl.com/no_image_available.png';
/**
* @var string
* @ORM\Column(type="text")
* @Assert\NotBlank()
*/
protected $description;
/**
* @var bool
* @ORM\Column(type="boolean", nullable=true)
*/
protected $isi_required;
/**
* @var string
* @ORM\Column(type="text", nullable=true)
*/
protected $isi_text;
/**
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $isi_pdf_url;
/**
* @var bool
* @ORM\Column(type="boolean", nullable=true)
*/
protected $pi_required;
/**
* @var string
* @ORM\Column(type="text", nullable=true)
*/
protected $pi_text;
/**
* @var string
* @ORM\Column(type="string", length=255, nullable=true)
*/
protected $pi_pdf_url;
/**
* @var bool
* @ORM\Column(type="boolean")
*/
protected $inactive = false;
/**
* @var string
* @ORM\Column(type="string", length=45, nullable=true)
*/
protected $template_name;
/**
* @var Company
* @ORM\ManyToOne(targetEntity="Company", inversedBy="brands")
* @ORM\JoinColumn(name="companies_id", referencedColumnName="id", nullable=true)
*/
protected $company;
/**
* @ORM\OneToMany(targetEntity="TargetBrand" , mappedBy="brand", cascade={"persist"}, orphanRemoval=true)
* */
protected $targetBrand;
/**
* @ORM\OneToMany(targetEntity="TerritoryBrand" , mappedBy="brand", cascade={"persist"}, orphanRemoval=true)
* */
protected $territoryBrand;
public function __construct()
{
$this->targetBrand = new ArrayCollection();
$this->territoryBrand = new ArrayCollection();
}
...
}
If I understood right each time that you load your form you are filling the brands
field with your query. This query select brands that has none companies. So when you try to edit some company the field is filled with this query. You should make a different query when you are editing, you can get the object with $this->getSubject();
and check if it is new.
A example solution:
$obj = $this->getSubject()->getId();
if(empty($obj)) {
$query = $em->createQueryBuilder('b')
->select('b')
->from('PDOneBundle:Brand', 'b')
->where('b.company IS NULL');
} else {
$query = $em->createQueryBuilder('b')
->select('b')
->from('PDOneBundle:Brand', 'b')
->where('b.company == :company_id');
$query->setParameter('company_id', $obj->getCompany());
}