2011-03-03 11 views
7

Tengo un modelo de video simple en mi aplicación de rieles que has_many comentarios. Estoy mostrando estos comentarios en la página de la demostración del video. Cuando envío el formulario todo funciona bien; Sin embargo, si hay errores de validación en el modelo de Comentario, mi sistema explota. Si hay errores de validación en el modelo de Comentario, simplemente me gustaría volver a mostrar la página de la presentación del video, mostrando el estilo de error de validación. ¿Cómo hago esto dentro de mi acción de crear? ¡Muchas gracias!¿Dónde renderizar el controlador de comentarios en Rails en el caso de las validaciones del modelo?

class CommentsController < ApplicationController 
    def create 
    @video = Video.find(params[:video_id]) 
    @comment = @video.comments.build(params[:comment]) 
    if @comment.save 
     redirect_to @video, :notice => 'Thanks for posting your comments.' 
    else 
     render # what? What do I render in order to show the video page's show action with the validation error styling showing? Please help! 
    end 
    end 
end 

Respuesta

10

Para hacer esto usted tendrá que hacer una plantilla:

class CommentsController < ApplicationController 
    def create 
    @video = Video.find(params[:video_id]) 
    @comment = @video.comments.build(params[:comment]) 
    if @comment.save 
     redirect_to @video, :notice => 'Thanks for posting your comments.' 
    else 
     render :template => 'videos/show' 
    end 
    end 
end 

Tenga en cuenta que tendrá que declarar las variables de instancia (como @video) en el interior de la CommentsController # crea Sin embargo, también se debe tener en cuenta que, dado que la acción show de VideoController no se ejecutará, la plantilla simplemente se representará. Por ejemplo, si tiene una variable @video_name en su acción VideoController # show, tendrá que agregar la misma variable de instancia @video_name a la acción CreateController # create.

+0

¡Impresionante, muchas gracias! – agentbanks217

7

Tengo el mismo problema. Creo que su pregunta es un duplicado de Rails validation over redirect (y también se ha duplicado más recientemente por custom validations errors form controller inside other parent controller rails 3.1).

El problema con la solución anterior por Pan Thomakos es que si VideosController#show tiene más de una cantidad no trivial de código en él, entonces no sería capaz de hacer de la plantilla videos/show sin violar la regla SECO. Aquí hay un related discussion.

This post from Ryan Bates de fama de Railscasts sugiere que podría almacenar @video en el flash para persistir a través de la redirección; sin embargo, cuando trato de hacer eso, sale del otro lado como una instancia de la clase correcta, pero no tiene ninguna de las superclases que cabría esperar, lo más importante es ActiveRecord::Base. Al principio pensé que tal vez su consejo simplemente no estaba actualizado (fue escrito en 2006). Sin embargo, una de las respuestas a Rails validation over redirect escrita en octubre de 2009 defiende el mismo enfoque, aunque a través de un método personalizado clone_with_errors que toma una copia superficial de la instancia del modelo para evitar problemas con objetos más profundos. Pero incluso con ese enfoque, los métodos que dependen de superclases no funcionan. Supongo que esto es una consecuencia del objeto que se serializa en el flash y luego se deserializa.

Encontré un page written in 2007 which advocates against storing model object instances in the session.

También encontré un good argument in the formtastic google group pointing out that redirecting on validation failure is not the Rails Way, y probablemente sea una mala idea. Pero esto aún no proporciona una buena solución en el caso de que intervengan controladores múltiples. Quizás Cells podría usarse para resolver el problema SECO mencionado anteriormente.

De lo contrario, supongo que la única respuesta es atenerse a los datos simples persistentes, como identificaciones de objeto, cadenas de mensajes de error, y así sucesivamente.

Cuestiones relacionadas