Я пытаюсь внедрить коллекцию форм в приложение symfony2. У меня есть простые объекты: Shop
и Address
whith Shop, который имеет несколько адресов. Я следую за Symfony2 documentation, но я получаю сообщение об ошибке:Ошибка при встраивании коллекции форм в Symfony2
Ни свойство "адрес", ни один из методов "GetAddress()", адрес "()", "isAddress()", «hasAddress() "," __get() "существуют и имеют открытый доступ в классе" AppBundle \ Entity \ Address ". 500 Internal Server Error - NoSuchPropertyException
Мне кажется, что он пытается получить доступ к address
preoperty моего Address Entity
.
Вот мой Shop Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\Address;
use UserBundle\Entity\Seller;
/**
* Shop
*
* @ORM\Table(name="app_shop")
* @ORM\Entity(repositoryClass="AppBundle\Repository\ShopRepository")
*/
class Shop
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
* @ORM\Column(name="shopName", type="string", length=255)
*/
private $shopName;
/**
* @var string
* @ORM\Column(name="description", type="text", nullable=true)
*/
private $description;
/**
* @var string
* @ORM\Column(name="ownerName", type="string", length=255)
*/
private $ownerName;
/**
* @ORM\ManyToOne(targetEntity="UserBundle\Entity\Seller", cascade={"refresh"}, fetch="EAGER")
* @ORM\JoinColumn(nullable=false, onDelete="NO ACTION")
* @Assert\Valid()
*/
private $owner;
/**
* @ORM\OneToMany(targetEntity="AppBundle\Entity\Address", mappedBy="shop")
* @Assert\Valid()
*/
private $address;
/**
* @ORM\Column(type="string", nullable=true)
* @Assert\Length(
* min = 9,
* max = 10,
* minMessage = "Le numéro siret doit contenir 10 chiffres",
* maxMessage = "Le numéro siret doit contenir 10 chiffres"
*)
*/
private $siret;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Image")
* @ORM\JoinColumn(nullable=true)
*/
private $image;
public function __construct()
{
$this->address = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set shopName
*
* @param string $shopName
* @return Shop
*/
public function setShopName($shopName)
{
$this->shopName = $shopName;
return $this;
}
/**
* Get shopName
*
* @return string
*/
public function getShopName()
{
return $this->shopName;
}
/**
* Set shopName
*
* @param string $description
* @return Shop
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Set ownerName
*
* @param string $ownerName
* @return Shop
*/
public function setOwnerName($ownerName)
{
$this->ownerName = $ownerName;
return $this;
}
/**
* Get ownerName
*
* @return string
*/
public function getOwnerName()
{
return $this->ownerName;
}
/**
* Set siret
*
* @param string $siret
* @return Shop
*/
public function setSiret($siret)
{
$this->siret = $siret;
return $this;
}
/**
* Get siret
*
* @return string
*/
public function getSiret()
{
return $this->siret;
}
/**
* Set address
*
* @param ArrayCollection $address
*
* @return Address
*/
public function setAddress(ArrayCollection $address)
{
$this->address = $address;
return $this;
}
/**
* Get address
*
* @return \AppBundle\Entity\Address
*/
public function getAddress()
{
return $this->address;
}
/**
* Set owner
*
* @param \UserBundle\Entity\Seller $owner
*
* @return Owner
*/
public function setOwner(Seller $owner = null)
{
$this->owner = $owner;
return $this;
}
/**
* Get owner
*
* @return \UserBundle\Entity\Sellers
*/
public function getOwner()
{
return $this->owner;
}
/**
*
* @param Image $image
* @return \AppBundle\Entity\Shop
*/
public function setImage(Image $image)
{
$this->image = $image;
return $this;
}
/**
*
*/
public function getImage()
{
return $this->image;
}
}
Вот мой Address Entity
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Adress
*
* @ORM\Table(name="app_address")
* @ORM\Entity(repositoryClass="AppBundle\Repository\AddressRepository")
*/
class Address
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="street", type="string", length=255)
* @Assert\Length( min = 5 ,
* max = 200,
* minMessage = "L'adresse doit faire au minimum {{ limit }} caractères.",
* maxMessage = "L'adresse doit faire au maximum {{ limit }} caractères.")
*
*/
private $street;
/**
* @ORM\Column(type="string", length=5)
* @Assert\Regex(
* pattern="/^\d{4,5}$/",
* match=true,
* message="Le format n'est pas correct"
*)
*/
private $postalCode;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $city;
/**
* @var string
*
* @ORM\Column(name="country", type="string", length=255 , nullable=true)
* @Assert\Length( min = 3 ,
* max = 50,
* minMessage = "Le pays doit faire au minimum {{ limit }} caractères.",
* maxMessage = "L'adresse doit faire au maximum {{ limit }} caractères.")
*
*/
private $country;
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Shop", inversedBy="address")
* @ORM\JoinColumn(name="shop_id", referencedColumnName="id")
*/
private $shop;
/**
* Get id
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* Set street
*
* @param string $street
*
* @return Address
*/
public function setStreet($street)
{
$this->street = $street;
return $this;
}
/**
* Get street
*
* @return string
*/
public function getStreet()
{
return $this->street;
}
/**
* Set postalCode
* @return Address
*/
public function setPostalCode($postalCode)
{
$this->postalCode = $postalCode;
return $this;
}
/**
* Get postalCode
*/
public function getPostalCode()
{
return $this->postalCode;
}
/**
*
* @param string
* @return \AppBundle\Entity\Address
*/
public function setCity($city = null)
{
$this->city = $city;
return $this;
}
/**
*
*/
public function getCity()
{
return $this->city;
}
/**
*
* @param string
* @return \AppBundle\Entity\Address
*/
public function setCountry($country = null)
{
$this->country = $country;
return $this;
}
/**
*
*/
public function getCountry()
{
return $this->country;
}
/**
*
* @param Shop
* @return \AppBundle\Entity\Address
*/
public function setShop($shop = null)
{
$this->shop = $shop;
return $this;
}
/**
*
*/
public function getShop()
{
return $this->shop;
}
public function __toString() {
return $this->street." ".$this->postalCode." ".$this->city;
}
}
Я создал два formType для того, чтобы управлять своей сущностью:
ShopType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use AppBundle\Form\AddressType;
use AppBundle\Entity\Shop;
use AppBundle\Entity\Address;
class ShopType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('shopName', TextType::class, array('label' => 'Nom du magasin *', 'required' => true, 'error_bubbling' => true))
->add('ownerName', TextType::class, array('label' => 'Nom du gérant *', 'required' => true, 'error_bubbling' => true))
->add('address', CollectionType::class, array( 'entry_type' => AddressType::class,
'allow_add' => true,
'label' => 'Adresse *',
'required' => true
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Shop::class,
));
}
}
AddressType.php
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Entity\Address;
class AddressType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('address', TextType::class, array('label' => 'Adresse*', 'required' => true))
->add('CodePostal', TextType::class, array('label' => 'Code postal*', 'required' => true, 'error_bubbling' => true))
->add('Ville', TextType::class, array('label' => 'Ville', 'required' => false, 'error_bubbling' => true))
->add('Pays', 'choice', array(
'choices' => array(
'FR' => 'France',
'SU' => 'Suisse',
'BE' => 'Belgique'
)
))
;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Address::class,
));
}
public function getName()
{
return 'addresse';
}
}
В моем контроллере, я instanciating своей формы следующим образом:
$shop = $shopRepo->findOneByOwner($user);
if ($shop == null){
$shop = new Shop();
}
$form = $this->createForm(ShopType::class , $shop);
Большое спасибо за ваше объяснение. Я рад, что вы «подтвердили» мое отношение OneToMany, я не был уверен в этом. Кроме того, спасибо за исправление моего магазина! – Gauthier