扩展注册FOSUserBundle表单以寻找不正确的方法

时间:2013-08-28 10:01:44

标签: forms symfony fosuserbundle

我正在使用FOSUserBundle,我在注册新用户时扩展了注册表单以输入公司名称。 Company是一个单独的实体。我为关系处理创建了所有必需的方法。

/**
 * User entity
 */
class User {
    // ...
    addCompany() { /* ... */ }
    removeCompany() { /* ... */ }
    getCompanies() { /* ... */ }
}

我关注了Symfony guide to embed a Single Object to a form

class RegistrationFormType extends \FOS\UserBundle\Form\Type\RegistrationFormType
{
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('...')
            ->add('company', new CompanyType());
    }
    // ...
}

登记表格正确;它显示公司名称的字段。但是当我提交时,我得到了

  

属性“company”和“setCompany()”,“_ set()”或“ _call()”之一都不存在,并且在“Acme \ MyBundle”类中具有公共访问权限\实体\用户”。

我显然既没有company属性也没有setCompany()方法,因为它是manyToMany关系,因此我有companies属性和addCompany()方法代替。

问题

  • Symfony为什么不寻找addCompany()方法?
  • 我应该实施setCompany()方法(例如,通过简单地重命名,还是作为调用addCompany()的包装方法)?
  • 或者这是由于Symfony无法正确解释单数和复数方法名称时出现的单数/复数问题?

1 个答案:

答案 0 :(得分:3)

你所追求的是by_reference选项。

有两种情况:

  1. by_reference => true因此会调用setter(默认情况下)。

  2. by_reference => false因此会调用加法器。

  3. 你要做的就是:

    How to Embed a Collection of Forms


    编辑1:OP希望用户加法器而不是setter

    试试这个:

    $builder->add('company', 'collection', array(
        'type'   => new CompanyType(),
        'options'  => array(
            'by_reference'  => false,
        ),
    ));
    

    编辑2:OP希望每个用户只创建一个公司

    class UserController extends Controller
    {
        public function whateverAction(Request $request)
        {
            $user = new User();
    
            $company = new Company();
            $user->getCompany()->add($company);
    
            $form = $this->createForm(new UserType(), $user);
    
            $form->handleRequest($request);
    
            if ($form->isValid()) {
                // form processing
            }
    
            return $this->render('AcmeUserBundle:User:new.html.twig', array(
                'form' => $form->createView(),
            ));
        }
    }
    

    编辑3:OP只想覆盖FOSUserBundle表单类型

    您仍然可以选择在实体中创建一个setter来解决您的问题。

    /**
     * Set Category
     *
     * @param ArrayCollection $category
     */
    public function setCategory($category) {
    
        $this->category->clear();
    
        foreach ($category as $cat) {
            $this->addCategory($cat);
        }
    
        return $this;
    }
    

    注意: 如果你有一个 OneToMany ,那么使用$ categories而不是$ category会更好一些,这样你就知道了这是一个集合。你将在你的实体中拥有:

    • $公司
    • getCompanies()
    • setCompanies($公司)
    • addCompany($公司)
    • removeCompany($公司)