在保持状态的同时渲染另一个控制器的视图

时间:2009-10-10 14:05:52

标签: ruby-on-rails

我有一个博客模型,有许多模型评论关系。

所以我的表单在博客节目视图中看起来像这样:

<% form_for [@blog, @comment] do |f| -%>
  <%= f.error_messages %>

  <%= f.label :message, "Add your message" %>
  <%= f.text_area :message %>

  <%= f.submit "Submit" %>
<% end -%>  

一切都非常简单。

我在评论控制器中有一个操作,这是一个创建操作。

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

  respond_to do |format|
    if @comment.save
      flash[:success] = "Thank you for your comment"
      format.html { redirect_to :back }
    else
      format.html { render :action => "new" }
    end
  end
end

我的问题是,当评论模型中出现验证错误时,我将最终呈现不存在的新评论视图。 我想渲染博客节目视图以及错误消息。 如果我尝试重定向或渲染博客节目视图模板,则用户评论最终会被删除,因为它们之间不会保留状态。 谁能告诉我这个问题的传统解决方案是什么?感谢。

2 个答案:

答案 0 :(得分:1)

解决方案是让您的博客为accept_nested_attributes_for:comments。

只通过博客控制器修改评论,您将确保在出现问题时返回博客视图并进行验证。

需要做出的改变才能使其发挥作用。

class Blog < ActiveRecord::Base
  ...
  accepts_nested_attributes_for :comments
end

博客/展示视图

<% form_for @blog do |f| -%>
  <%= f.error_messages %>
  <% new_comments @blog.comments.select{&:new_record?} %>
  <%= f.fields_for :comments, new_comments.empty? ? @blog.comments.build : new_comments do |c| %>
  <%= c.label :message, "Add your message" %>
  <%= c.text_area :message %>
  <%=end%>

  <%= f.submit "Submit" %>
<% end -%>

如果Blog控制器中没有更新方法,则需要添加以使其正常工作。但我相信这对于宁静的路线来说并不是必需的,因为铁路将采取共同的行动。但是,这可能还需要您拥有与show视图几乎相同的博客编辑视图。而是在控制器中使用此代码。

class BlogsController < ApplicationController
  def update
    @blog = Blog.find(params[:id])
    if @blog.update_attributes(params[:blog])
      redirect_to @blog
    else
      render :action => show
    end
  end
end

如果您对Blog模型使用attr_accessible,则必须在列表中添加:comments。

答案 1 :(得分:0)

KJF,

你会想要做这样的事情:

before_filter :fetch_blog

def create
  @comment = @blog.comments.new(params[:comment])
  respond_to do |format|
    if @comment.save
      flash[:success] = "Thank you for your comment"
      format.html { redirect_to blog_path(@blog) }
    else
      format.html { render :controller => 'blog', :action => 'show' }
    end
  end
end

protected
  def fetch_blog
    @blog = Blog.find(params[:blog_id])
  end