验证通过另一个控制器调用的表单

时间:2012-02-21 17:12:21

标签: ruby-on-rails forms validation

我正在编写一个博客引擎,所以我有一个帖子视图(show.html.erb),显示帖子,评论列表和评论表单。

我这样称呼表单:

<%= render :partial => 'comments/form', :locals => {:comment => @post.comments.new} %>

我不确定以这种方式传递评论是否正确,但至少我在新评论中得到了post_id。

这是我的表单(评论视图上的_form.html.erb):

<%= form_for comment, :action => "create" do |f| %>
    <% if comment.errors.any? %>
        <div id="error_explanation">
          <h2><%= pluralize(comment.errors.count, "error") %> prohibited this comment from being added:</h2>

          <ul>
            <% comment.errors.full_messages.each do |msg| %>
                <li><%= msg %></li>
            <% end %>
          </ul>
        </div>
    <% end %>

  <%= f.hidden_field :post_id %>
  <p>
    <%= f.label :name %>
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :email %>
    <%= f.text_field :email %>
  </p>
  <p>
    <%= f.label :url %>
    <%= f.text_field :url %>
  </p>
  <p>
    <%= f.label :content %>
    <%= f.text_area :content %>
  </p>
  <p class="no-border">
    <%= f.submit "Post", :class => "button" %>
  </p>
<% end %>

这就是行动:

  def create
    @comment = Comment.new(params[:comment])

    respond_to do |format|
      if @comment.save
        format.html { redirect_to :back }
      else
        format.html { redirect_to :back }
      end
    end
  end

有点冗长,但我想添加更多内容。

我可以完美地添加评论,但我无法查看验证错误。

我将所有内容留空(我的模型有验证内容),并且我看到创建操作中创建的评论有错误并转到其他路径。< / p>

但是......表格没有显示任何错误。

我认为我有一个带有erorrs的对象,但是当我重定向回来时,我传递给表单的对象又是一个新对象,并没有错误。

那么,问题在哪里?

编辑:额外的东西:

我的show.html.erb我也有这个(在表单之前):

<ol class="commentlist">
  <%= render @post.comments %>
</ol>

所以,在 show 操作中,我放了额外的变量:

def show
  @post = Post.find(params[:id])
  @comment = @post.comments.new

似乎渲染器也想渲染空注释并发出异常。

如何绕过它?

1 个答案:

答案 0 :(得分:1)

当您重定向时,您再次调用PostsController#show操作,这将重置所有实例变量。如果您想在失败的CommentsController#create调用后保存状态,则需要调用render 'posts/show'而不是redirect :back,这将重用在当前操作中声明的实例变量

def create
   # assuming you have nested the comments routes underneath posts...
   @post = Post.find(params[:post_id])
   @comment = @post.comments.build(params[:comment])

   respond_to do |format|
      if @comment.save
         format.html { redirect_to :back }
      else
         format.html do
            # remember to declare any instance variables that PostsController#show requires
            # e.g. @post = ...
            render 'posts/show'
         end
      end
   end
end

您还需要确保部分使用@comment而不是每次都创建新评论

<%= render :partial => 'comments/form', :locals => {:comment => @comment } %>

并确保PostsController声明@comment

# e.g. inside PostsController
def show
   @post = Post.find(params[:id])
   @comment = Comment.new
end

要记住的最重要的事情是确保失败的create调用中的代码初始化PostsController#show操作模板所需的所有实例变量,否则您将收到错误。