Estoy escribiendo una forma de asistente en rieles; p.ej. múltiples páginas de entrada para un objeto modelo.¿Cómo validar un objeto de modelo anidado basado en el estado del objeto primario?
Los fundamentos de mi enfoque son los descritos en Ryan Bates 'Multistep form railscast: http://railscasts.com/episodes/217-multistep-forms (en caso de que alguien quiera saber el POR QUÉ detrás de algunos de los códigos a continuación).
Los objetos bajo escrutinio aquí son "Participante", que tiene una "dirección"
Mi problema es que yo sólo quiero validar el objeto anidado (Dirección) cuando el usuario está tratando de progresar más allá de la entrada de direcciones pantalla. Esto es seguido actualmente a través de un atributo en el modelo de participante llamado "CURRENT_STEP"
Así que tienen un Participante:
class Participant < ActiveRecord::Base
has_one :address
accepts_nested_attributes_for :address
validates_presence_of :first_name, :last_name, :if => self.current_step == "name"
...
def steps = %w[ name address confirm ] # the steps the wizard will follow
end
y una dirección:
class Address < ActiveRecord::Base
belongs_to :participant
validates_presence_of :address1, :state, :suburb, :postcode #, :if => participant.current_step == "address"
end
El principio de este método es el La acción "crear" se invoca en el controlador (no se muestra) para cada paso del asistente, y solo valida un subconjunto del modelo cuando se procesa cada paso.
Actualmente, cuando completo la primera pantalla ("nombre") y trato de ir al paso de la dirección, la validación de la dirección se activa y me devuelven a la pantalla "nombre" con errores de validación de la dirección en blanco detalles.
Así que he intentado una serie de enfoques aquí, la parte final de la cual fue la condición comentada en validación de dirección que se muestra arriba - esto he encontrado que no funciona ya que solo estoy construyendo participantes-> objetos de dirección , pero no salvarlos. Por lo tanto, @participant.address
me da el objeto de dirección, pero @participant.address.participant
es nulo, ya que la dirección aún no tiene una clave externa participante_id para buscarla.
El motivo de mis problemas parece ser la inclusión del super-práctico accepts_nested_attributes_for
método. Esperaba usar un validates_associated
para hacer la validación, pero veo que la etiqueta accepts_nested_attributes_for
propaga parámetros de forma muy bien para crear objetos de modelo anidados, pero también asegura que el método participant#valid?
llama a la validación de direcciones en TODAS las situaciones.
Entonces mi dilema es cómo usar mejor el método participant#valid?
para validar el modelo parcialmente completo, basado en el parámetro current_step
en el participante?
EDITAR - actualizado para eliminar información adicional, y destilar hasta el problema central
Solo una conjetura, pero ha intentado valida: address,: if => Proc.new {| participante | participante.current_step == 'nombre'} – dogenpunk
Una de las primeras cosas que intenté, pero como se menciona arriba (quizás no demasiado claro, lo admito) el objeto de dirección no tiene participante hasta que se guarda, por lo que recibí un error al llamar a current_step una clase nula – Phantomwhale
Agregue: inverso de sus relaciones, por lo que el objeto de dirección tendrá una referencia a su participante cuando se construya. – graywh