Skip to content

Latest commit

 

History

History
130 lines (97 loc) · 3.63 KB

forms.rst

File metadata and controls

130 lines (97 loc) · 3.63 KB

Using Models in Forms

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.

Binding the Object to the Form

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

Form Type Guessing

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

Form Validation

As the properties cannot be defined explicitly in the model, validating them is a bit more difficult. There are a couple solutions here:

  1. Don't bind models to your form, but instead create a new class specifically for your form;
  2. 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;
    }
}

« Migrations and SeedingEvents and Observers »