Este foro ya no está activo, así que no puedes publicar nuevas preguntas ni responder a las preguntas existentes.

Formulario con un select dependiente de una entidad

23 de diciembre de 2014

Buenos dias, mi problema es el siguiente:

Tengo una entidad llamada Reserva, que tiene dos entidades, Usuarios e Invitados.

Los invitados están relacionados con los usuarios. La idea es que me muestre los invitados del usuario seleccionado, que no se puede cambiar, asi que no me hace falta AJAX ni nada similar.

Mi duda es, como puedo pasarle la variable usuario a la consulta personalizada de los invitados. No se si me he explicado correctamente, si necesitáis que publique el código, no hay problema.

Saludos


Respuestas

#1

Las dos alternativas más comunes para hacer esto se explican en esta pregunta de StackOverflow.

La forma más sencilla sería pasar el usuario como opción desde el controlador al crear el formulario:

$form = $this->createForm(new ReservaType(), new Reserva(), array(
    'usuario' => $this->getUser()
));

Y luego ya en el formulario utilizas la opción usuario dentro de la consulta para obtener los invitados:

use Doctrine\ORM\EntityRepository;
// ...
 
$builder->add('invitados', 'entity', array(
    'class' => 'AppBundle:Invitado',
    'query_builder' => function(EntityRepository $er) use ($usuario) {
        return $er->createQueryBuilder('i')
            ->where('i.invitado =:usuario')->setParameter('usuario', $usuario)
            ->orderBy('i.nombre', 'ASC');
    },
));

La otra forma de hacerlo es más "profesional", pero te costará mucho más trabajo. La idea consiste en definir el formulario como servicio e inyectar en el constructor del formulario el objeto usuario que se utilizará en la consulta.

@javiereguiluz

23 diciembre 2014, 9:26
#2

La cuestion es que mi formulario es un servicio y necesitaria la opcion compleja.

PD: Gracias por responder tan rapido

@TsubasaAkai

23 diciembre 2014, 9:30
#3

Si tu formulario ya es un servicio, entonces la otra solución no es "la compleja", sino "la correcta". En tu caso ya tienes casi todo el trabajo hecho, sólo te faltaría inyectar el servicio relacionado con el contexto de la seguridad para poder obtener el objeto del usuario y así poder utilizarlo en la consulta.

@javiereguiluz

23 diciembre 2014, 9:34
#4

¿Y eso como lo hago exactamente?

@TsubasaAkai

23 diciembre 2014, 9:36
#5

1. Modifica la definición del servicio de tu formulario para añadir la nueva dependencia del servicio security.context:

<services>
    <service id="app.form.reserva.type" class="AppBundle\Form\Type\ReservaType">
        <tag name="form.type" alias="reserva" />
        <argument type="service" id="security.context" /> <!-- AÑADE ESTA LÍNEA -->
    </service>
</services>

2. Añade o modifica el constructor de tu formulario para recoger este nuevo servicio que se le pasa al instanciar el formulario:

namespace AppBundle\Form\Type;
 
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Security\Core\SecurityContextInterface;
use Symfony\Component\Security\Core\User\UserInterface;
 
class ReservaType extends AbstractType
{
    /**
     * @var UserInterface
     */
    private $user;
 
    /**
     * @param string $class
     */
    public function __construct(SecurityContextInterface $securityContext)
    {
        $this->user = $securityContext->getRequest->getUser();
    }
 
    // ...
}

3. Usa la nueva propiedad $user para obtener el nombre del usuario (o su login, su email, etc.) para realizar la consulta:

namespace AppBundle\Form\Type;
 
// ...
 
class ReservaType extends AbstractType
{
    // ...
 
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $username = $this->user->getUsername();    
 
        $builder->add('invitados', 'entity', array(
            'class' => 'AppBundle:Invitado',
            'query_builder' => function(EntityRepository $er) use ($username) {
                return $er->createQueryBuilder('i')
                    ->where('i.invitado =:usuario')->setParameter('usuario', $username)
                    ->orderBy('i.nombre', 'ASC');
            },
        ));
    }
}

@javiereguiluz

23 diciembre 2014, 10:30
#6

Muchas gracias!

¿Pero con esto obtengo el usuario logeado o el usuario que tengo seleccionado?

Saludos

@TsubasaAkai

23 diciembre 2014, 10:47
#7

Tienes razón: con este código obtienes el usuario logueado y lo que tu quieres es poder seleccionar el usuario que tú quieras. En ese caso es más sencillo, ya que no tienes que inyectar el servicio de seguridad. Simplemente obtén el usuario en el controlador y pásalo como opción del formulario, tal y como se mostraba en el primer ejemplo de esta discusión.

@javiereguiluz

23 diciembre 2014, 12:17
#8

Muchas gracias, al final lo sulucione de esa manera, pero me acabas de resolver un problme futuro.

Muchas gracias!

@TsubasaAkai

24 diciembre 2014, 10:53