在Rails中的当前视图中呈现表单错误

时间:2015-07-26 03:30:46

标签: ruby-on-rails ruby forms render

我有一个MainPagesController索引页面,它从QuotesController呈现具有表单的“新”页面。如何使用表单错误呈现MainPagesController索引页?

MainPages /索引

<h1>Welcome to Book Quotes</h1>
<p>
  Post your favourite quotes from your favourite books
  <%= render 'quotes/new' %>
</p>
<%= render 'quotes/all_quotes' %>

股票报价/新

<h1>Add a quote</h1>
<%= render 'quotes/form' %>

行情/ _form

<%= form_for @quote do |f| %>
  <% if @quote.errors.any? %>
    <ul>
    <% @quote.errors.full_messages.each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  <% end %>
  <p>
    <%= f.label :passage %><br>
    <%= f.text_field :passage %>
  </p>
  <p>
    <%= f.label :book_title %><br>
    <%= f.text_field :book_title %>
  </p>
  <p>
    <%= f.label :book_author %><br>
    <%= f.text_field :book_author %>
  </p>
  <p>
    <%= f.submit %>
  </p>
<% end %>

QuotesController

def create
  @quote = Quote.new(quote_params)
  if @quote.save
    redirect_to root_url
  else
    render #not sure what goes here
  end
end

1 个答案:

答案 0 :(得分:1)

由于您正在处理的表单是嵌套表单,render :new的标准建议不会帮助您。相反,您可以将用户重定向回索引页面,通过闪存传递错误,并更新视图以处理显示这些错误。

(只是一个想法:可能值得研究一下这个动作是由AJAX提供的。用户体验可能更好,它简化了你的代码设计。)

无论如何,在你的QuotesController中,#create操作需要记下错误并将它们传递给用户,因为它将用户重定向回原来的位置:

def create
  @quote = Quote.new(quote_params)
  if @quote.save
    redirect_to root_url
  else
    flash[:quote_errors] = @quote.errors.full_messages
    redirect_to :back # or main_pages_path
  end
end

然后,您的Quotes / _form视图需要处理这些错误:

<%= form_for @quote do |f| %>
  <% if flash[:quote_errors] %>
    <ul>
    <% flash[:quote_errors].each do |msg| %>
      <li><%= msg %></li>
    <% end %>
    </ul>
  <% end %>
  # ...

现在,这有点难看。您可能想知道 - 我们不能通过闪存传递@quote对象,因此视图不必更改?虽然这在技术上是可行的,但将对象序列化为会话是一条危险的路径。我建议避免它。

另一个选择是使报价提交不是在QuotesController上,而是在MainPages控制器上。如,

class MainPagesController < ApplicationController
  def index
    # ...
  end

  def create_quote
    @quote = Quote.new(quote_params) # need to move quote_params in, too
    if @quote.save
      redirect_to root_url
    else      
      render :index
    end
  end
  # ...

这允许从表单中访问@quote实例变量,因此错误处理as-is将正常工作。它不是非常RESTful,但是再一次,大多数前端网站都没有。