Corregir la devolución de llamada del modelo ROR para la creación asociada

tengo modelos asociados User y Channel en la aplicación Rails 3. Channel se crea en el momento de User creación

class User < ActiveRecord::Base
  before_create do
    self.channels.build
  end
  has_many :channels  
end    

class Channel < ActiveRecord::Base
  belongs_to :user
  validations block
  ...
end

El problema es que si las validaciones para Channel no pasan User se creará en DB pero Channel no. ¿En qué lugar de devolución de llamada? Channel creación para crear User y Channel en una 'transacción'? O, tal vez, ¿hay otra manera correcta?

Gracias de antemano.

UPD1: Channel crear automáticamente en User crear colocado en el modelo porque en algunos casos los objetos creados no invocan controladores.

preguntado el 16 de abril de 13 a las 08:04

3 Respuestas

Puede usar "accepts_nested_attributes_for"

clase Usuario <ActiveRecord :: Base
tiene_muchos: canales
accepts_nested_attributes_for :canales
final

clase Canal < ActiveRecord::Base
pertenece_ a: usuario
bloque de validaciones
final

Respondido 16 Abr '13, 08:04

Tu piensas demasiado. Este es un caso muy común y tiene una convención.

En primer lugar, dijo Pedro, necesita una validación de asociación en el modelo de Canal. Esto evitará guardar el canal sin user_id.

Luego, en el controlador create acción, solo asegúrese de que todos los parámetros, incluido el objeto de usuario, se envíen aquí para su creación.

Respondido 16 Abr '13, 08:04

No coloqué el código de creación de asociación en el controlador sino en el modelo porque en algunas circunstancias el controlador no se usa, por ejemplo: llamar User.create! de otro modelo. - maxim kachalin

@MaksimKachalin, no puedo pensar en ningún caso de uso en el que deba poner la lógica de manipulación de registros en otro modelo en lugar del controlador. Si lo tiene, es mejor que lo actualice en la pregunta. Gracias. - Billy Chan

Gracias. He actualizado la pregunta. En la pregunta pedí otra forma quizás más correcta. ¿Crees que la lógica debe colocarse en el controlador? - maxim kachalin

@MaksimKachalin, te sugiero que abandones esta idea. Esto no es una convención. Si desea crear un canal en Usuario, ¿qué canal va a crear? ¿De dónde provienen los datos? Estos son todos los trabajos del controlador. - Billy Chan

Utilice las validates :channels, associated: true.

Probablemente deberías revisar las validaciones de tu canal porque si no se está guardando, estás haciendo algo que tu aplicación no espera.

Respondido 16 Abr '13, 08:04

Por supuesto validaciones para Channel falla porque estoy probando este comportamiento ahora mismo. validates :channels, associated: true añadido a User el modelo no tiene efecto, ejecutar db:seed: u = User.create() u.save todavía crea User mientras que no Channel. - maxim kachalin

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.