在模型验证失败的Rails中哪里呈现注释控制器?

时间:2011-03-03 00:54:22

标签: ruby-on-rails controller render

我的rails应用中有一个简单的视频模型has_many评论。我在视频的节目页面上显示这些评论。当我提交表格时,一切正常;但是,如果评论模型上存在验证错误,那么我的系统就会爆炸。如果评论模型上存在验证错误,我只想再次渲染视频的显示页面,并显示验证错误样式。如何在我的创建操作中执行此操作?非常感谢!

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

2 个答案:

答案 0 :(得分:10)

要执行此操作,您必须呈现模板:

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

请记住,你必须在CommentsController #create动作中声明任何实例变量(如@video),因为不会运行VideosController#show动作,模板将被简单地渲染。例如,如果您在VideosController#show action中有@video_name变量,则必须将相同的@video_name实例变量添加到CommentsController #create操作。

答案 1 :(得分:7)

我有同样的问题。我认为您的问题与Rails validation over redirect重复(最近也由custom validations errors form controller inside other parent controller rails 3.1重复。)

Pan Thomakos上述解决方案的问题在于,如果VideosController#show中包含的代码数量超过了非常重要的数量,那么您将无法在不违反videos/show模板的情况下进行渲染干旱规则。这是一个related discussion

This post from Ryan Bates Railscasts的名声表明你可以将@video存储在flash中,以便在重定向中保留它;但是当我尝试这样做时,它会作为正确类的一个实例出现在另一侧,但它没有你期望的任何超类 - 最重要的是ActiveRecord::Base。起初我想也许他的建议已经过时了(它是在2006年写的)。但是,2009年10月撰写的Rails validation over redirect的答案之一提出了相同的方法,尽管通过自定义clone_with_errors方法获取模型实例的浅层副本以避免更深层对象的问题。但即使采用这种方法,依赖于超类的任何方法都不起作用。我猜这是将对象序列化到flash中然后反序列化的结果。

我找到了page written in 2007 which advocates against storing model object instances in the session

我还找到了good argument in the formtastic google group pointing out that redirecting on validation failure is not the Rails Way,可能是一个坏主意。但是,在涉及多个控制器的情况下,这仍然不能提供良好的解决方案。也许Cells可以用来解决上面提到的DRY问题。

否则我猜唯一的答案是坚持持久化的简单数据,如对象ID,错误消息字符串等。