No insertar campos null en Symfony 3

B

Hola a tod@s!

He realizado un formulario en symfony que funciona perfectamente si relleno todos los campos, pero si alguno de ellos lo dejo vacío me da un error cuando va a insertar a la base de datos porque no puede insertar campos null. Si por ejemplo dejo el campo foto sin rellenar me aparece el siguiente error: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'foto' cannot be null

Los campos de esta tabla estan configurados como Nulo=no

Si yo realizo un INSERT, desde la consola, indicando los campos que están rellenados, los inserta correctamente.

Alguien sabe como puedo hacer en symfony, para que sólo me inserte en la base de datos aquellos campos que se han introducido?

Muchas gracias por adelantado.

Un saludo.

sh31k

Puedes poner el código?

Me da que estas forzando una recepción de datos en el controlador y al no enviarla desde la vista intenta insertar vacío y de ahí el error.

eXtreM3

Ponle un valor por defecto a los campos no nulos. Por ejemplo al de la foto ponle "sinfoto.jpg"

2 respuestas
B

Entity Clientes:

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * Clientes
 *
 * @ORM\Table(name="clientes", uniqueConstraints={@ORM\UniqueConstraint(name="numcliente", columns={"numcliente"})}, indexes={@ORM\Index(name="apellidos", columns={"apellidos"}), @ORM\Index(name="codigotargeta", columns={"codigotargeta"}), @ORM\Index(name="apellidos_2", columns={"apellidos"}), @ORM\Index(name="email", columns={"email"})})
 * @ORM\Entity
 */
class Clientes
{
    /**
     * @var integer
     *
     * @ORM\Column(name="numcliente", type="integer", nullable=false)
     */
    private $numcliente;

    /**
     * @var string
     *
     * @ORM\Column(name="nombre", type="string", length=60, nullable=false)
     */
    private $nombre;

    /**
     * @var string
     *
     * @ORM\Column(name="apellidos", type="string", length=200, nullable=false)
     */
    private  $apellidos;

/**
     * @var string
     *
     * @ORM\Column(name="movil", type="string", length=20, nullable=false)
     */
    private $movil;
/**
     * @var string
     *
     * @ORM\Column(name="foto", type="blob", length=16777215, nullable=false)
     */
    private $foto;

 /**
     * Set numcliente
     *
     * @param integer $numcliente
     *
     * @return Clientes
     */
    public function setNumcliente($numcliente)
    {
        $this->numcliente = $numcliente;

    return $this;
}

/**
 * Get numcliente
 *
 * @return integer
 */
public function getNumcliente()
{
    return $this->numcliente;
}

/**
 * Set nombre
 *
 * @param string $nombre
 *
 * @return Clientes
 */
public function setNombre($nombre)
{
    $this->nombre = $nombre;

    return $this;
}

/**
 * Get nombre
 *
 * @return string
 */
public function getNombre()
{
    return $this->nombre;
}

/**
 * Set apellidos
 *
 * @param string $apellidos
 *
 * @return Clientes
 */
public function setApellidos($apellidos)
{
    $this->apellidos = $apellidos;

    return $this;
}

/**
 * Get apellidos
 *
 * @return string
 */
public function getApellidos()
{
    return $this->apellidos;
}

/**
     * Set movil
     *
     * @param string $movil
     *
     * @return Clientes
     */
    public function setMovil($movil)
    {
        $this->movil = $movil;

    return $this;
}

/**
 * Get movil
 *
 * @return string
 */
public function getMovil()
{
    return $this->movil;
}

/**
     * Set foto
     *
     * @param string $foto
     *
     * @return Clientes
     */
    public function setFoto($foto)
    {
        $this->foto = $foto;

    return $this;
}

/**
 * Get foto
 *
 * @return string
 */
public function getFoto()
{
    return $this->foto;
}
}

ClientesController.php

class ClientesController extends Controller
{
public function nuevoClienteAction(Request $request)
    {   
$cliente = new Clientes(); $form = $this->createForm(\AppBundle\Form\ClientesType::class,$cliente); $form->handleRequest($request);
if ($form->isSubmitted()&& $form->isValid()) { //Recoge los datos $cliente = $form->getData(); // you can fetch the EntityManager via $this->getDoctrine() // or you can add an argument to your action: createAction(EntityManagerInterface $em) $em = $this->getDoctrine()->getManager(); // tells Doctrine you want to (eventually) save the Product (no queries yet) $em->persist($cliente); // actually executes the queries (i.e. the INSERT query) $em->flush(); return $this->redirect($this->generateUrl( 'clientes')); } return $this->render('clientes/nuevoclienteprueba.html.twig',array('formulario'=>$form->createView())); } }

ClientesType.php

class ClientesType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{ //setMethod('PATCH')->
$builder->
add('numcliente', IntegerType::class)->
add('nombre', TextType::class,array('label' => 'Nombre','attr' => array('class' => 'form-control','placeholder' => 'Nombre')))->
add('apellidos', TextType::class,array('label' => 'Apellidos','attr' => array('class' => 'form-control','placeholder' => 'Apellidos')))->
add('movil', TextType::class,array('label' => 'Móvil','attr' => array('class' => 'form-control','placeholder' => 'Teléfono Móvil')))->
add('foto', FileType::class,array('label' => 'Foto','required' => '','attr' => array('class' => 'form-control')))->
add('guardar',SubmitType::class, array('label' => 'Guardar','attr' => array('class' => 'btn green')))->getForm();
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Clientes'
));
}

/**
 * {@inheritdoc}
 */
public function getBlockPrefix()
{
    return 'appbundle_clientes';
}

}

B

#3 Gracias por contestar eXtreM3, pero me gustaría que si ve que esta vacío el campo, no lo quiera insertar.
Si tengo que ir campo por campo dándole valores por defecto, no me parece muy eficiente.
Espero que exista otra forma.

2 respuestas
sh31k

#5 Y si controlas en los setters que el campo no esté vacío?

Merkury

#5 Basicamente si quieres que el campo se quede vacio tiene que ser nullable=true

/**
     * @var string
     *
     * @ORM\Column(name="foto", type="blob", length=16777215, nullable=true)
     */
    private $foto;

Despues de este cambio, haz un

php bin\console d:s:u --force

Y a volar

Porque no haces un dump del profiler cuando te da el error en la cosulta a ver si es que tienes algo mas mal.

Ese required en el FormType para foto, no te ayuda, ademas que esta incompleto.

PiPePiTo

#3 tus cojones x'D

Turco

#1 Si sólo quieres que se inserten aquellos campos que has introducido, ¿cual es el motivo por en el que la entidad tienes todos los campos nullable=false? Es decir, estás declarando que ningún campo pueda estar vacío, sin embargo, al formulario puede no rellenársele ciertos campos. No tiene sentido.

Ponle un nullable=false a aquellos campos que SIEMPRE deben rellenarse, y al restro nullable=true y ya. Luego haz un php bin/console doctrine:schema:update --force

Si no puedes tocar la bbdd por alguna razón, de modo que ningún campo pueda ser null, deberás meterle siempre un valor por defecto. Esto lo haces asignándole un valor a la variable en la entidad. Por ejemplo:

private $nombre = '-';

Si el usuario no rellena ese campo, por defecto se le pondrá lo que has definido, en caso contrario, se seteará el valor que se ha introducido en e formulario.

Usuarios habituales