【问题标题】:Rendering form errors in the current view in Rails在 Rails 的当前视图中呈现表单错误
【发布时间】:2015-07-26 03:30:46
【问题描述】:

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

主页/索引

<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

【问题讨论】:

  • 尝试给render :new看看它是否有效。
  • render :new 渲染了带有表单错误的引号控制器新视图,但不会让我在表单所在的同一页面中。我想留在 MainPagesController 索引视图中,但显示带有错误的表单

标签: ruby-on-rails ruby forms render


【解决方案1】:

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

(只是一个想法:可能值得考虑让这个动作由 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 实例变量,因此按原样处理错误就可以正常工作。它不是很 RESTful,但话又说回来,大多数前端网站流程也不是。

【讨论】:

  • 我没有想过以这种方式实现它。谢谢罗伯特!我已经使用了 flash 方式,并且效果很好。
猜你喜欢
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
  • 2014-10-07
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
  • 2015-02-27
  • 2016-07-06
相关资源
最近更新 更多