The eloquent models can work perfectly with forms. However, due to the lazyness of models, you have to do things a little bit different than documented in the Symfony documentation.
Creating forms is done exactly the same as normal (refer to the Symfony documentation if you don't know how this is done normally):
namespace AppBundle\Controller;
use AppBundle\Model\Post;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\HttpFoundation\Request;
class PostController extends Controller
{
public function createAction(Request $request)
{
$post = new Post();
$form = $this->createFormBuilder($post)
->add('title', TextType::class)
->add('body', TextareaType::class)
->getForm();
$form->handleRequest($form);
if ($form->isSubmitted() && $form->isValid()) {
$post->save();
return $this->render('post/create_success.html.twig');
}
return $this->render('post/create_form.html.twig', [
'form' => $form->createView(),
]);
}
}
If you use Eloquent attribute casting, the bundle is able to guess your form types. For instance, assume this model:
namespace AppBundle\Model;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public $casts = [
'title' => 'string',
'published_at' => 'date',
'is_published' => 'boolean',
'body' => 'string',
];
}
Then you can generate your form like this:
$form = $this->createFormBuilder(new Post())
->add('title')
->add('published_at')
->add('is_published')
->add('body', TextareaType::class) // string is always transformed to TextType
->getForm();
As the properties cannot be defined explicitly in the model, validating them is a bit more difficult. There are a couple solutions here:
- Don't bind models to your form, but instead create a new class specifically for your form;
- Define getters for all your properties and validate the return values.
The second solution would look like this:
namespace AppBundle\Model;
use Illuminate\Database\Eloquent\Model;
use Symfony\Component\Validator\Constraints as Assert;
class Post extends Model
{
public $casts = [
'title' => 'string',
'published_at' => 'date',
'is_published' => 'boolean',
'body' => 'string',
];
/**
* @Assert\NotBlank
* @Assert\Length(max=128)
*/
public function getTitle()
{
return $this->title;
}
/** @Assert\NotBlank */
public function getBody()
{
return $this->body;
}
}