在Symfony2中嵌入表单集合时出错

时间:2016-12-20 17:38:23

标签: php forms symfony doctrine-orm

我正在尝试在symfony2应用程序中嵌入一组表单。我必须使用简单的实体:ShopAddress,其中一个商店有多个地址。我按照Symfony2 documentation但我收到了错误:

  

属性“地址”和方法“getAddress()”之一,   “address()”,“isAddress()”,“hasAddress()”,“__ get()”存在并具有   “AppBundle \ Entity \ Address”类中的公共访问。 500内部服务器   错误 - NoSuchPropertyException

在我看来,它正试图访问我address的{​​{1}}个主页。

这是我的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

我创建了两个formType来管理我的实体:

ShopType.php

<?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;
    }
}

AddressType.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,
        ));
    }
}

在我的控制器中,我正在设置我的表格如下:

<?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';
    }
}

1 个答案:

答案 0 :(得分:3)

由于AddressType类:

处的此行而发生此错误

->add('address', TextType::class, array('label' => 'Adresse*', 'required' => true))

您正在尝试访问address实体的Address属性,但它并不包含它。这与其他字段相关:CodePostal =&gt; postalCode

同样在您的Shop实体,您address字段注明为OneToMany关系,这是正常的,同时您有setAddress(ArrayCollection $address)方法,但您应该有:

public function addAddress(Address $address)
{
    $this->address->add($address);

    return $this;
}

和可选

public function removeAddress(Address $address)
{
    $this->address->remove($address);

    return $this;
}

顺便说一下,我建议将属性address重命名为addresses,以突出显示它应该包含集合,但不应包含单个实体。