2010-03-05 14 views
9

Estoy tratando de crear un registro dentro de una tabla de unión desde la acción de un botón. Tendría un modelo de eventos y me gustaría rastrear eventos seleccionados de cada usuario.Rieles - Agregar registro para unir la tabla desde el controlador

Utilicé la relación HABTM ya que realmente no necesito campos adicionales.

User.rb:

has_to_and_belongs_to_many :events 

Event.rb:

has_to_and_belongs_to_many :users 

Events_Users Migración:

[user_id, event_id, id=>false] 

Me estoy atascado en la creación real del registro. Alguien me ayudó antes con añadir el registro en la consola de:

u = User.find(1) 
u.events << Event.find(1) 

Ahora me gustaría realizar la acción como resultado de hacer clic en un enlace ... ¿Es esto en la dirección correcta?

def add 
    @user = User.find(session[:user_id]) 
    @event = Event.find(params[:id]) 
    if @user.events.save(params[:user][:event]) 
    flash[:notice] = 'Event was saved.' 
    end 
end 

¿Debo añadir un @user.events.new algún lugar y si es así ¿por dónde poner los parametros de qué usuario y qué evento?

Respuesta

13

El siguiente código debería funcionar (suponiendo que se pasa en un parámetro con el identificador de nombre que corresponde a la ID de un objeto de evento):

def add 
    @user = User.find(session[:user_id]) 
    @event = Event.find(params[:id]) 
    @user.events << @event 
    flash[:notice] = 'Event was saved.' 
    end 

Los problemas que veo en el código son:

  1. Usted está pasando un hash a .save. Guardar solo debe tomar un valor booleano correspondiente a si las validaciones se deben ejecutar y es verdadero de manera predeterminada. Sin embargo, .create y .new pueden aceptar un hash de valores. (.save se usaría después de .new).

  2. Carga un evento a través de params [: id] pero luego intenta crear un evento a través de params [: usuario] [: evento]. ¿Qué quieres hacer? Crear o cargar? (mi ejemplo asume la carga)

  3. Las acciones que tienen un efecto como este deberían ocurrir cuando un usuario hace clic en un botón y envía un formulario en lugar de 'hacer clic en un enlace'. Este código puede ser vulnerable a la falsificación de solicitudes entre sitios (alguien podría engañar a alguien para que haga clic en un enlace en otro sitio que ejecutó esta acción). Los formularios de rieles, si se implementan correctamente, están protegidos contra esto porque usan un token de protección de falsificación de solicitud.

  4. Lo más probable es que desee redirigir al usuario después de esta acción. Hacer páginas después de ejecutar acciones como esta (en lugar de redirigir) se considera una mala práctica.

+0

Qué quiere decir @ user.events << @ event.name ??? – ChrisWesAllen

+0

No. Ese código no tendría sentido si entiendo la descripción del problema correctamente. – Gdeglin

+0

Gracias por las sugerencias, cambié el "<% = link_to image_tag (" grid_heart.gif ",: border => 0),: controller => 'event',: action => 'add_event'%>" to "< % = button_to "Agregar",: controller => 'event',: action => "add"%> "pero sigo teniendo un error de que haya un" EventController constante no inicializado "¿Puse el método en el controlador equivocado? – ChrisWesAllen

3

Lo que hizo en la consola que necesita hacer en el controlador.

def add 
    @user = User.find(session[:user_id]) 
    @event = Event.find(params[:id]) 
    @user.events << @event 
    flash[:notice] = 'Event was saved.' 
end 

Lo que hay que tener en cuenta es que el operador < < para los registros existentes hará que la asociación que se persistió inmediatamente.

Eche un vistazo a the ActiveRecord documentation para obtener más información.

0

Si el event_id se pasa como params [: id] y que está agregando un único evento en esta llamada a continuación, puede hacer lo siguiente en su código del controlador:

User.find(session[:user_id]).events << Event.find(params[:id]) 
    flash[:notice] = 'Event was saved.' 

No es necesario explícita save para guardar la asociación has_many de una instancia de modelo existente.

Escenario 1

u = User.new(..) 
u.events << Event.first 
# Now you need to call `save` in order to save the user object 
# and the events association 
u.save 

Escenario 2

u = User.first 
u.events << Event.first 
# Don't need to call `save` on `u` OR `u.events` 
+0

Todavía obtengo un Constante no inicializada EventController ¿Alguna idea de dónde podría venir? – ChrisWesAllen

+0

Puedes publicar tu código de controlador en Pastie (http://pastie.org/) y proporcionar un enlace. –

+0

Puedo, pero ese es el único método que agregué al event_controller. No hay ningún error cuando elimino el método de agregar, y el resto del controlador se generó desde un andamio, por lo que es bastante básico. El método actual se parece a ... def añadir \t \t @user = User.find (sesión [: user_id]) \t \t @event = Event.find (params [: id]) \t \t @user. eventos << @event \t \t flash [: notice] = 'Se guardó el evento.' \t final – ChrisWesAllen

Cuestiones relacionadas