扩展注册FOSUserBundle表单寻找不正确的方法 [英] Extending registration FOSUserBundle form looking for improper methods

查看:163
本文介绍了扩展注册FOSUserBundle表单寻找不正确的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  / ** 
*用户实体
* /
class用户{
// ...
addCompany(){/ * ... * /}
removeCompany(){/ * ... * /}
getCompanies(){/ * ... * /}
}

Symfony指南将单个对象嵌入到表单中< a>:

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

注册表格被正确渲染;它显示公司名称的字段。但是,当我提交时,我得到


属性company和方法setCompany(),_ set()或 _call()存在并且在类Acme\MyBundle\Entity\User中具有公共访问权。

我显然既没有公司属性也没有 setCompany()方法,因为它是manyToMany关系,所以我有一个公司属性和一个 addCompany()方法。



问题


  • 为什么Symfony不会寻找 addCompany()方法?

  • 我应该实现 setCompany() ,或者作为一个包装方法来调用 addCompany())?

  • 或者这是由于出现单数/复数问题当单数和复数方法名称不能被Symfony正确解释时?


解决方案

你在做什么是 by_reference 选项。

有2种情况:


  1. by_reference => true ,因此调用者被调用(默认情况下)。

  2. false ,因此调用加法器。 正是这个:



    How嵌入一​​个表单集合






    编辑1:OP希望用户加法器代替setters



    试试这个:

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






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



      class UserController extends Controller 
    {
    public function anyAction(Request $ request)
    {
    $ user = new User();

    $ company = new Company();
    $ user-> getCompany() - > add($ company);

    $ form = $ this-> createForm(new UserType(),$ user);

    $ form-> handleRequest($ request);
    $ b $ if($ form-> isValid()){
    //表单处理
    }

    返回$ this-> render(' AcmeUserBundle:User:new.html.twig',array(
    'form'=> $ form-> createView(),
    ));


    $ / code $ / pre

    $ hr

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



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

      / ** 
    *设置类别
    *
    * @param ArrayCollection $ category
    * /
    public function setCategory($ category){

    $ this-> category-> clear();

    foreach($ category as $ cat){
    $ this-> addCategory($ cat);
    }

    返回$ this;
    }

    注意: 如果您有 OneToMany ,那么使用$ categories而不是$ category将会是更好的做法,以便您知道它是一个集合。您需要在您的实体中:


    • $ companies

    • getCompanies()

    • setCompanies($ companies)

    • addCompany($ company)

    • removeCompany($ company)


    I am using the FOSUserBundle and I extended the registration form to input the name of a company when registering a new user. Company is a separate Entity. I created all required methods for the relation handling.

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

    I followed the 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());
        }
        // ...
    }
    

    The registration form is rendered properly; it shows a field for the Company name. But when I submit, I get

    Neither the property "company" nor one of the methods "setCompany()", "_set()" or "_call()" exist and have public access in class "Acme\MyBundle\Entity\User".

    I obviously neither don't have a company property nor a setCompany() method, because it's a manyToMany relationship, thus I have a companies property and a addCompany() method instead.

    Questions

    • Why doesn't Symfony also look for a addCompany() method?
    • Should I implement a setCompany() method (e.g. by simply renaming accordingly, or as a wrapper method which calls addCompany())?
    • Or is this due to the singular/plural problem which comes up when singular and plural method names can't be interpreted correctly by Symfony?

    解决方案

    What you're after is the by_reference option.

    There are 2 cases:

    1. by_reference => true and therefore the setters are called (by default).

    2. by_reference => false and therefore the adders are called.

    What you're trying to do is exactly this : 

    How to Embed a Collection of Forms.


    Edit 1: The OP wishes to user adders instead of setters

    Try this:

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


    Edit 2: The OP wishes to create only one company per user

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


    Edit 3: The OP only wants to override the FOSUserBundle form type

    You still have the option to create a setter in your entity to solve your issue.

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

    Note: It would be a better practice to use $categories instead of $category if you have a OneToMany so that you know that it's a collection. You would have in your entity:

    • $companies
    • getCompanies()
    • setCompanies($companies)
    • addCompany($company)
    • removeCompany($company)

    这篇关于扩展注册FOSUserBundle表单寻找不正确的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆