问题
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 callsaddCompany()
)? - 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?
回答1:
What you're after is the by_reference option.
There are 2 cases:
by_reference => true
and therefore the setters are called (by default).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)
来源:https://stackoverflow.com/questions/18484826/extending-registration-fosuserbundle-form-looking-for-improper-methods