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 %> . . . 

我知道我在后面的例子中使用了@postvariables,但是我在前者中引用了什么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_messagesf.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调用之外的所有行中,只用@postreplace@post实例variables。

我认为将@comment = @post.comment.build添加到显示此表单的控制器方法并使用form_for([@post, @comment], ...)来保留表单内容也是一个好主意如果出现错误,则在表单中显示。

如果这不起作用,你不能解决它,请添加您的CommentsController#create方法的问题。