Subscribe via RSS or know about updates first by getting on the newsletter.
Learning to program doesn't have to be so hard. Reading scattered blog posts and books isn't as effective as watching real projects being built and actively coding along with them. SymfonyCasts bridges that learning gap, bringing you video tutorials and interactive coding activities. Code on!
Though not required, we typically, bind Symfony form objects to a class (often an entity). This means that the field names must correspond with the property names on the class (well actually, the getter/setter methods, via the PropertyAccess component):
// ...
class ProductFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text')
->add('price', 'number');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefault('data_class', 'AppBundle\Model\Product');
}
// ...
}
Since this has name
and price
fields, the Product
class must also have the
methods getName()
, setName()
, getPrice()
and setPrice()
:
// ...
class Product
{
private $name;
private $price;
public function getName()
{
return $this->name;
}
public function setName($name)
{
$this->name = $name;
}
public function getPrice()
{
return $this->price;
}
public function setPrice($price)
{
$this->price = $price;
}
}
But the mapping doesn't actually use the field's name (e.g. price
) to find the
getters/setters. In the background, each field has a property_path
option, which defaults to the field name. This means that the field names could
be something entirely different than the property name, as long as the property_path
is set:
// ProductFormType.php
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('productName', 'text', [
'property_path' => 'name'
])
->add('mainPrice', 'number', [
'property_path' => 'price'
]);
}
When would this be useful? Suppose the Product
object has a related Category
object:
class Product
{
// ...
/**
* @var Category
*/
private $category;
public function getCategory()
{
return $this->category;
}
public function setCategory(Category $category)
{
$this->category = $category;
}
}
What if you want the user to be able to edit the category's title
property, right
inside the Product form? That can be done by using embedded forms.
Or, you can leverage property_path
:
// ProductFormType.php
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text')
->add('price', 'number')
->add('categoryTitle', 'text', [
'property_path' => 'category.title'
]);
}
The key is category.title
, which leverages the PropertyAccess component and means
that $product->getCategory()->getTitle()
and $product->getCategory()->setTitle()
are called in the background when the form is loaded and saved.
Now, note that this won't change the Category from one to another: you're actually modifying the title of the same object. You also need to make sure that the Product has a Category, or else the PropertyAccess component can't call down the path. But, depending on your situation, this might be the perfect (and simplest) solution.
Cheers!