Rails 当前视图中的渲染表单错误
Rendering form errors in the current view in Rails
我有一个 MainPagesController 索引页,它呈现来自具有表单的 QuotesController 的 'new' 页面。如何呈现带有表单错误的 MainPagesController 索引页?
MainPages/index
<h1>Welcome to Book Quotes</h1>
<p>
Post your favourite quotes from your favourite books
<%= render 'quotes/new' %>
</p>
<%= render 'quotes/all_quotes' %>
Quotes/new
<h1>Add a quote</h1>
<%= render 'quotes/form' %>
Quotes/_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
的标准建议在这里对您没有帮助。相反,您可以将用户重定向回索引页面,通过 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 %>
# ...
现在,这有点难看。您可能想知道——难道我们不能通过 Flash 将 @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,但话又说回来,大多数前端网站流量也不是。
我有一个 MainPagesController 索引页,它呈现来自具有表单的 QuotesController 的 'new' 页面。如何呈现带有表单错误的 MainPagesController 索引页?
MainPages/index
<h1>Welcome to Book Quotes</h1>
<p>
Post your favourite quotes from your favourite books
<%= render 'quotes/new' %>
</p>
<%= render 'quotes/all_quotes' %>
Quotes/new
<h1>Add a quote</h1>
<%= render 'quotes/form' %>
Quotes/_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
的标准建议在这里对您没有帮助。相反,您可以将用户重定向回索引页面,通过 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 %>
# ...
现在,这有点难看。您可能想知道——难道我们不能通过 Flash 将 @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,但话又说回来,大多数前端网站流量也不是。