Rails 3.0中的frorror_messages
Rails 3.0弃用f.error_messages
,现在需要一个插件来正常工作 – 但我想学习如何显示错误消息的(新)本地方式。 我正在遵循入门指南 ,该指南在实现注释表单时使用了弃用的方法。 例如:
<h2>Add a comment:</h2> <%= form_for([@post, @post.comments.build]) do |f| %> <%= f.error_messages %> <div class="field"> <% f.label :commenter %><br /> <%= f.text_field :commenter %> </div> <div class="field"> <%= f.label :body %><br /> <%= f.text_area :body %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
这是正确的方法(由脚手架产生):
<%= form_for(@post) do |f| %> <% if @post.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% @post.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> </div> <% end %> . . .
我知道我在后面的例子中使用了@post
variables,但是我在前者中引用了什么variables来获取创build注释的错误消息?
我只是看着docrails的github问题,他们已经决定删除f.error_messages而不是解释如何做评论的validation。
在窗体中实现error_messages的最好和干净的方法是在FormBuilder中实现error_messages。
例如,这里是我为最后一个项目实现的error_messages方法。 通过实现你自己的FormBuilder你可以遵循你的webdesigner的规则和样式…这里是一个例子,将输出ul / li的错误列表与一些自定义样式:
class StandardBuilder < ActionView::Helpers::FormBuilder def error_messages return unless object.respond_to?(:errors) && object.errors.any? errors_list = "" errors_list << @template.content_tag(:span, "There are errors!", :class => "title-error") errors_list << object.errors.full_messages.map { |message| @template.content_tag(:li, message) }.join("\n") @template.content_tag(:ul, errors_list.html_safe, :class => "error-recap round-border") end end
然后以我的forms:
= f.error_messages
就这样。
我很确定你需要做的是参考@post.comments
所以你可以做这样的事情:
<% @post.comments.each do |comment| %> <% if comment.errors.any? %> <% comment.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> <% end %> <% end %>
或者把所有的错误都拿出来
comment_errors = @post.comments.map(&:errors)
然后在显示逻辑中循环显示每个注释错误。
这个function作为一个独立的gem dynamic_form存在。
将以下内容添加到您的Gemfile
gem 'dynamic_form'
从github页面 :
DynamicForm拥有一些帮助者方法来帮助你处理你的Rails3模型,它们是:
-
input(record, method, options = {})
-
form(record, options = {})
-
error_message_on(object, method, options={})
-
error_messages_for(record, options={})
它还将f.error_messages
和f.error_message_on
添加到表单构build器。
这是我对整个错误场景的解决scheme。
我创build了一个简单的使用模型variables的部分:
<%# app/views/errors/_error.html.erb %> <%= content_for :message do %> <% if model.errors.any? %> <ul> <% model.errors.full_messages.each do |msg| %> <li><%= msg %></li> <% end %> </ul> <% end %> <% end %>
您可以根据模型的名称和通用名称轻松添加dynamichtml类和/或id名称。
我有东西安装在我的错误消息呈现在布局文件中的所有相同的地方:
<%# app/views/layouts/application.html.erb %> <%= yield :message %>
如果一个人不想要这个function,那么删除部分中的content_for就可以了。
然后在任何你想要的视图中,你可以简单地写下:
<%= render 'errors/error', model: @some_model %>
人们可以通过创build一个部分来进一步扩展这个部分,这个部分需要一个集合并且利用部分上面的错
<%# app/views/errors/_collection.html.erb %> <% collection.each do |model| %> <%= render 'errors/error', model: model %> <% end %>
渲染:
<%= render 'errors/collection', collection: @some_model.some_has_many_association %>
我喜欢这种方式。 它很简单,容易pipe理/维护,并且令人难以置信的可调整。
我希望这有帮助!
编辑:在HAML的一切
-# app/views/errors/_error.html.haml = content_for :message do - if model.errors.any? %ul - model.errors.full_messages.each do |msg| %li= msg
-# app/views/layouts/application.html.haml = yield :message
= render 'errors/error', model: @some_model
-# app/views/errors/_collection.html.haml - collection.each do |model| = render 'errors/errors', model: @some_model
= render 'errors/_collection', collection: @some_model.some_has_many_association
我想[@post, @post.comments.build]
数组刚刚传递给form_for
polymorphic_path
。 这会为注释生成一个子资源path(如本例中的/posts/1/comments
)。 所以它看起来像你的第一个例子使用评论作为post的子资源,对吧?
所以实际上这里将被调用的控制器是CommentsController
。 Lukas的解决scheme不适合你的原因可能是你在创build注释时实际上不使用@ post.comments.build(在调用form_for
)。 CommentsController#create
方法应该看起来像这样(或多或less):
def create @post = Post.find(params[:post_id] @comment = @post.comments.build(params[:comment]) if(@comment.save) # you would probably redirect to @post else # you would probably render post#show or wherever you have the form end end
然后你可以使用scaffolding生成的代码,除了form_for
调用之外的所有行中,只用@post
replace@post
实例variables。
我认为将@comment = @post.comment.build
添加到显示此表单的控制器方法并使用form_for([@post, @comment], ...)
来保留表单内容也是一个好主意如果出现错误,则在表单中显示。
如果这不起作用,你不能解决它,请添加您的CommentsController#create
方法的问题。