2011-04-01 15 views
7

Estoy comenzando una aplicación de rails 3 que tiene un modelo principal y un modelo hijo (padre has_ ​​many: children).¿Cómo puedo pasar mensajes de error de validación a un método en un controlador diferente?

Estoy tratando de configurar las cosas para que después de crear un nuevo padre, el usuario pase a la acción de mostrar de ese padre (/ padre/id). En esta vista, he incluido parciales para mostrar cualquier hijo y un formulario para crear un nuevo hijo. Después de crear un nuevo hijo, el usuario se redirige a la acción de mostrar para el padre donde aparecerá el nuevo hijo. Todo esto funciona según lo previsto.

Sin embargo, si intento validar campos en el formulario hijo nuevo, los mensajes de error que aparecen no aparecen en el formulario (las líneas necesarias en la vista están ahí y son correctas, cortadas y pegadas desde el código de andamio generado). ¿Hay alguna manera de pasar estos mensajes de error para el niño con éxito a la acción de demostración principal?

Aquí hay fragmentos de códigos relevantes;

Desde mi controlador de matriz:

def show 
    @parent = Parent.find(params[:id]) 
    @child = @parent.children.new 

    respond_to do |format| 
    format.html # show.html.erb 
    format.xml { render :xml => @admission } 
    end 
end 

Desde mi regulador del niño:

def create 
    @child = Child.new(params[:parent]) 

    respond_to do |format| 
    if @child.save 
     format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') } 
       #This works as intended 
     format.xml { render :xml => @child, :status => :created, :location => @child } 
    else 
     format.html { redirect_to parent_path(params[:child][:patient_id]) } 
       #This redirects where I want it to go when validation fails but error messages are lost 
     format.xml { render :xml => @child.errors, :status => :unprocessable_entity } 
    end 
    end 
end 

Respuesta

11

Bien, lo resolví yo mismo. Gracias por la respuesta de Terw. Funciona aparte de dar la URL incorrecta debido a la falta de redirección.

Fue simplemente una cuestión de pasar los errores a través del hash de la sesión y luego agregarlos al modelo secundario en el controlador principal.

Estoy publicando el código porque no pude encontrar ningún otro ejemplo de esto. Tal vez hay una manera más simple, pero esto funciona perfectamente hasta ahora. Si alguien piensa que estoy loco, por favor explíquelo.

En mi controlador de niño

def create 
    @parent = Parent.find(params[:child][:parent_id]) 
    @child = @parent.child.build(params[:child]) 

    respond_to do |format| 
    if @child.save 
     format.html { redirect_to(parent_path(params[:admission][:parent_id]), :notice => 'Child was successfully created.') } 
     format.xml { render :xml => @child, :status => :created, :location => @child } 
    else 
     if @child.errors.any? 
     session[:child_errors] = @child.errors 
     end 
     format.html { redirect_to(parent_path(params[:child][:parent_id])) } 
     format.xml { render :xml => @child.errors, :status => :unprocessable_entity } 
    end 
    end 
end 

Y en mi controlador de matriz

def show 
    @parent = Parent.find(params[:id]) 
    @child = @parent.children.new 
    if session[:child_errors] 
    session[:child_errors].each {|error, error_message| @child.errors.add error, error_message} 
    session.delete :child_errors 
    end 
    respond_to do |format| 
    format.html # show.html.erb 
    format.xml { render :xml => @parent } 
    end 
end 
1

¿Qué pasa si usted acaba de renderizar la página espectáculo de los padres si el niño no es válida?

def create 
    @child = Child.new(params[:parent]) 

    respond_to do |format| 
    if @child.save 
     format.html { redirect_to(parent_path(params[:child][:parent_id]), :notice => 'Child was successfully created.') } 
       #This works as intended 
     format.xml { render :xml => @child, :status => :created, :location => @child } 
    else 
     format.html { render :controller => :parent, :action => :show } 
       # Display the parent's show page to display the errors 
     format.xml { render :xml => @child.errors, :status => :unprocessable_entity } 
    end 
    end 
end 

Es posible que también desee hacer algo como esto para la acción del cajón para asegurarse de que el padre exista.

@parent = Parent.find(params[:parent][:parent_id]) 
@child = @parent.children.build(params[:parent]) 

Luego, sus usuarios no pueden crear un elemento secundario no válido, y usted tiene el elemento primario para volver a mostrar la página del programa. No debe dar a los usuarios la posibilidad de establecer parent_id ellos selfes.

+0

Gracias, eso tiene los mensajes de error mostrando que es un comienzo. (Lectura alrededor - render 'parents/show' es la forma correcta). El problema es que debido a que no hay redirección, la URL que se muestra no es válida. Este es un problema mucho más pequeño pero aún menos que ideal. Gracias por la sugerencia de cargar primero al padre (aunque un usuario malintencionado aún podría enviar fácilmente un parent_id válido pero incorrecto para adjuntar un hijo). Además, debe ser Parent.find (params [: child] [: parent_id]) y .build (params [: child]). No trato de ser pedante, simplemente intento ayudar a cualquier persona que lea esto. – brad

Cuestiones relacionadas