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
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
La cuestion es que mi formulario es un servicio y necesitaria la opcion compleja.
PD: Gracias por responder tan rapido
@TsubasaAkai
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
¿Y eso como lo hago exactamente?
@TsubasaAkai
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
Muchas gracias!
¿Pero con esto obtengo el usuario logeado o el usuario que tengo seleccionado?
Saludos
@TsubasaAkai
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
Muchas gracias, al final lo sulucione de esa manera, pero me acabas de resolver un problme futuro.
Muchas gracias!
@TsubasaAkai