Symfony 2:创建可以搜索的概览页面 - 总是从表单中得到错误 "should not be blank"

Symfony 2: Create overview page with possibility to search - always got errors from form "should not be blank"

我定义了表格:

class OrganizationSearchType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name', 'text', array('label' => 'Name', 'required' => false))
            ->add('category', 'text', array('label' => 'Kategorie', 'required' => false))
            ->add('street', 'text', array('label' => 'Strasse', 'required' => false))
            ->add('zip', 'text', array('label' => 'PLZ', 'required' => false))
            ->add('city', 'text', array('label' => 'Ort', 'required' => false))
            ->add('search', 'submit', array('label' => 'Suchen'));

    }

    public function getName()
    {
        return 'organization';
    }
}

TWIG:{#app/Resources/views/organization/overview.html.twig#}

{% extends 'base.html.twig' %}

{% block body %}
    <h2>Organistationen</h2>
    {{ form_start(searchForm) }}
    {{ form_errors(searchForm) }}
    <div>
        {{ form_label(searchForm.name) }}
        {{ form_widget(searchForm.name) }}
    </div>
    <div>
        {{ form_label(searchForm.category) }}
        {{ form_widget(searchForm.category) }}
    </div>
    <div>
        {{ form_label(searchForm.street) }}
        {{ form_widget(searchForm.street) }}
    </div>
    <div>
        {{ form_label(searchForm.zip) }}
        {{ form_widget(searchForm.zip) }}
    </div>
    <div>
        {{ form_label(searchForm.city) }}
        {{ form_widget(searchForm.city) }}
    </div>

    {{ form_end(searchForm) }}

    {% if searchDone %}
    {% if table|length > 0 %}

控制器:

/**
     * @Route("/organization")
     */
    public function showAll(Request $request)
    {
        $searchOrganization = new Organization();
        $repository = $this->getDoctrine()->getRepository('AppBundle:Organization');
        $availableCategories = $repository->getDistinctCategories();

        $selectCategories = array();
        for ($i=0; $i<count($availableCategories); $i++) {
            array_push($selectCategories, $availableCategories[$i]['category']);
        }

        $searchForm = $this->createForm(new OrganizationSearchType(), $searchOrganization);
        $searchForm->remove('category');
        $searchForm->add('category','choice', array('choice_list' => new ChoiceList($selectCategories, $selectCategories), 'label' => 'Kategorie', 'required' => false));
        $searchForm->handleRequest($request);

        if ($searchForm->isSubmitted()) {
            $name = $searchForm["name"]->getData();
            $category = $searchForm["category"]->getData();
            $street = $searchForm["street"]->getData();
            $zip = $searchForm["zip"]->getData();
            $city = $searchForm["city"]->getData();

            $searchOrganization = $repository->getBasicSearch($name, $category, $street, $zip, $city);
        } else {
            $searchOrganization = '';
        }

        return $this->render(
            'organization/overview.html.twig',
            array(
                'table' => $searchOrganization,
                'searchForm' => $searchForm->createView(),
                'searchDone' => $searchForm->isSubmitted(),
            )
        );
    }

所有字段都是可选的 - 如果它们没有内容,like-Statement 将搜索“%”。但我总是遇到错误 - 无法找到删除它们的可能性。

category [choice]

Errors

Message Origin  Cause
This value should not be blank. category    Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).data.category = null

city [text]

Errors

Message Origin  Cause
This value should not be blank. city    Symfony\Component\Validator\ConstraintViolation
Object(Symfony\Component\Form\Form).data.city = null

Class 组织:

<?php
// src/AppBundle/Entity/Product.php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="AppBundle\Entity\OrganizationRepository")
 * @ORM\Table(name="organization")
 */
class Organization
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=150)
     */
    protected $name;

    /** 
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=100)
     */
    protected $category;

    /**
     * @Assert\NotBlank() 
     * @ORM\Column(type="string", length=100)
     */
    protected $street;

    /**
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=20)
     */
    protected $zip;

    /**
     * @Assert\NotBlank()
     * @ORM\Column(type="string", length=100)
     */
    protected $city;

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Organization
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string 
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set category
     *
     * @param string $category
     * @return Organization
     */
    public function setCategory($category)
    {
        $this->category = $category;

        return $this;
    }

    /**
     * Get category
     *
     * @return string 
     */
    public function getCategory()
    {
        return $this->category;
    }

    /**
     * Set street
     *
     * @param string $street
     * @return Organization
     */
    public function setStreet($street)
    {
        $this->street = $street;

        return $this;
    }

    /**
     * Get street
     *
     * @return string 
     */
    public function getStreet()
    {
        return $this->street;
    }

    /**
     * Set zip
     *
     * @param string $zip
     * @return Organization
     */
    public function setZip($zip)
    {
        $this->zip = $zip;

        return $this;
    }

    /**
     * Get zip
     *
     * @return string 
     */
    public function getZip()
    {
        return $this->zip;
    }

    /**
     * Set city
     *
     * @param string $city
     * @return Organization
     */
    public function setCity($city)
    {
        $this->city = $city;

        return $this;
    }

    /**
     * Get city
     *
     * @return string 
     */
    public function getCity()
    {
        return $this->city;
    }
}

class OrganizationRepository extends EntityRepository
{
    public function getBasicSearch($name, $category, $street, $zip, $city) {
        $qb = $this->createQueryBuilder('organization');
        if ($name == '') {
            $name = '%';
        }
        if ($category == '') {
            $category = '%';
        }
        if($street == '') {
            $street = '%';
        }
        if($zip == '') {
            $zip = '%';
        }
        if($city == '') {
            $city = '%';
        }
        $qb->where(
            $qb->expr()->andX(
                $qb->expr()->like('organization.category', ':category'),
                $qb->expr()->like('organization.name', ':name'),
                $qb->expr()->like('organization.street', ':street'),
                $qb->expr()->like('organization.zip', ':zip'),
                $qb->expr()->like('organization.city', ':city')
            )
        )->setParameters(array('category' => $category, 'name' => $name, 'street' => $street, 'zip' => $zip, 'city' => $city));

        $res = $qb->getQuery();
        return $res->getResult();
    }

    public function getDistinctCategories() {
        $qb = $this->createQueryBuilder('organization');
        $qb->select(array('organization.category'));
        $qb->addGroupBy('organization.category');
        $qb->orderBy('organization.category');
        $res = $qb->getQuery();
        return $res->getResult();
    }
}

为什么要删除然后添加类别字段?

我认为这是问题所在。您应该通过构造函数或 setter 方法传递所需的参数,并在第一次正确地初始化表单。

错误来自对您实体的断言

/** 
 * @Assert\NotBlank()
 * @ORM\Column(type="string", length=100)
 */
protected $category

无论您在表单中放置什么,每次您在绑定到实体的表单上调用 isValid() 时,也会检查实体断言。这完全合情合理。

您必须修复您的代码

  • 从您的实体中删除断言
  • 从您的 FormType
  • 中删除 required => false

此外,您正在做一些不必要的额外工作,而且您做的方式是错误的。

  • 如果将对象绑定到表单,则不需要直接从表单检索数据
  • 如果您想列出可用类别,您可以将实体管理器传递给您的 FormType,如果需要,还可以设置默认值。

希望对您有所帮助