1

I have created a small Symfony (Sf3.2 + php7) web with a Task Entity. I have my controller where I have a new action to create a new task. Everything is fine. Now, some of the form fields are not necessary to be filled (created date, for example). So I have removed from my taskType:

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add->('name')->add('description');
}

Now my form looks exactly as I want. The surprise is that when I submit it my controller pass it to doctrine,and every missing field is write as a NULL. NO!, I don't want that, what I wanted is my default mysql value.

Ok, I read the doc. There seems to be two ways of handling data:

$form->handleRequest($request);
$form->submit($request->request->get($form->getName()));

I've found in the API, (not in the doc) that submit have a second parameter, a boolean:

API says:

bool    $clearMissing   Whether to set fields to NULL when they are missing in the submitted data.

Great! this is exactly what I need. Lets see it:

public function newAction(Request $request) {
    $task = new Task();

    $form = $this->createForm('myBundle\Form\TaskType', $task);
    $form->submit($request->request->get($form->getName()), false);
    if ($form->isSubmitted() && $form->isValid()) {


        $em = $this->getDoctrine()->getManager();
        $em->persist($task);
        $em->flush();
        $response = new Response();
        $response->setContent(json_encode(array(
            'data' => 'success',
        )));
        $response->headers->set('Content-Type', 'application/json');
        return $response;

        return $this->redirectToRoute('task_success');
    }
    return $this->render('task/new.html.twig', array(
                'task' => $task,
                'form' => $form->createView(),
    ));
}

Well, after tried everything I always get NULL in all missing fields. What am I doing wrong.

Thank you, Caterina.

I'm afraid there must be something more. And I was thinking that perhaps is not Doctrine the solution. The Symfony log shows me the insert and it's setting a Null in every empty field, on empty fields and missing fields. In fields like status i could set a default value, at doctrine level, but if I want to set created_at field, I suppose that must be Mysql the responsible is setting current timeStamp.

Anyway this is my ORM property status from Task Entity.

/**
 * @var \scrumBundle\Entity\Taskstatus
 *
 * @ORM\ManyToOne(targetEntity="scrumBundle\Entity\Taskstatus")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="status", referencedColumnName="id")
 * })
 * @ORM\Column(name="status", type="integer", nullable=false,options={"default":1})
 */
private $status;

And this is the property id from TaskStatus:

/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer", nullable=false, options={"default":1})
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="IDENTITY")
 */
private $id;

As you see I tried to follow your advise of setting the option default value. I've tried to create to set the form with handleRequest and submit with same result

$task = new Task();
$form = $this->createForm('scrumBundle\Form\TaskType', $task);
//$form->handleRequest($request);
$form->submit($request->request->get($form->getName()), false);
if ($form->isSubmitted() && $form->isValid()) {

I even tried to debug step by step submit function, a real Hell, because submit is a recursive function to much complex for me.

Ok , again thank for you time. Regards, Cate

PS. Sorry about my poor english.;^)

Jason Roman
  • 8,146
  • 10
  • 35
  • 40
  • You need to explicitly set the defaults in your Entity. Doctrine is always going to persist all fields from your entity so they will still be ` null` regardless of your form. Set a default on your ORM column definition, a LifecycleCallback, or your entity's constructor. Take a look here for some solutions. - https://stackoverflow.com/questions/3376881/default-value-in-doctrine – Jason Roman Jun 29 '17 at 14:59
  • Thank you very much! I had suspects about my entity. As soon I try it, i'll tell you – caterina gordo Jun 29 '17 at 15:46
  • Symfony 1 - Cate 0, see my edits. please help – caterina gordo Jun 30 '17 at 07:03

1 Answers1

1

Short answer - when you persist a PHP object through Doctrine, you must have absolutely every value set that you want. If your PHP object has null fields, Doctrine will manually set them as null in your entity. Doctrine doesn't assume that just because a value is null in your PHP object, that you don't want it included on your INSERT statement. This is because null is a perfectly valid SQL value.

So, whatever your PHP object is at the time of insert is exactly what is going to be inserted into your database, null values and all.

When you are editing an entry, Doctrine will only update the fields that are different, so this isn't a concern. Your concern is when persisting entities.

The easiest solution is to copy your MySQL default value into your PHP entity. Like one of these many ways:

// set default value on the variable itself
public $someVar = 100;

// set default values in the constructor (so when creating a new entry)
public function __construct()
{
    $this->createdAt = new \DateTime();
    $this->isActive  = true;
}

You can also use Lifecycle Callbacks to set when inserting a new entry:

/**
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks()
 */
class Task
{
    // ...

    /**
     * @ORM\PrePersist
     */
    public function setCreatedAtValue()
    {
        $this->createdAt = new \DateTime();
    }
}
Jason Roman
  • 8,146
  • 10
  • 35
  • 40