6

不获取<div class="fieldWithErrors">具有验证错误的包装环绕选择标签是正常行为吗?我个人认为没有理由将选择标签与其他表单标签(输入、文本区域)区别对待。

确实得到了该字段的错误error_messages_forerror_message_on方法。

PS。ActionView::Base.field_error_proc为了获得 span 标签而不是 div,我进行了一些更改,但这不是问题。

ActionView::Base.field_error_proc = Proc.new { |html_tag, instance|
   #if I puts html_tag here I only get the <input> tags
   "<span class=\"fieldWithErrors\">#{html_tag}</span>"
}
4

5 回答 5

4

问题(至少对我而言)是我f.select :whatever_idobject.errors对象中寻找:whatever_id我的验证实际打开时的键:whatever,而不是:whatever_id.

我通过更改解决了这个烦人的问题

object.errors.on(@method_name)

object.errors.on(@method_name) || object.errors.on(@method_name.gsub(/_id$/, ''))

这是差异(针对 Rails 2.3.4):

diff --git a/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb b/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb
index 541899e..5d5b27e 100644
--- a/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -247,7 +247,7 @@ module ActionView
       alias_method :tag_without_error_wrapping, :tag
       def tag(name, options)
         if object.respond_to?(:errors) && object.errors.respond_to?(:on)
-          error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
+          error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name) || object.errors.on(@method_name.gsub(/_id$/, '')))
         else
           tag_without_error_wrapping(name, options)
         end
@@ -256,7 +256,7 @@ module ActionView
       alias_method :content_tag_without_error_wrapping, :content_tag
       def content_tag(name, value, options)
         if object.respond_to?(:errors) && object.errors.respond_to?(:on)
-          error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name))
+          error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name) || object.errors.on(@method_name.gsub(/_id$/, '')))
         else
           content_tag_without_error_wrapping(name, value, options)
         end
于 2009-12-17T07:18:59.923 回答
3

因为我不知道为什么选择标签没有包含在那个 Proc 中,所以我创建了一个辅助方法,它做的事情几乎相同。

def field_with_error(object, method, &block)
  if block_given?
    if error_message_on(object, method).empty?
      concat capture(&block)
    else
      concat '<span class="fieldWithErrors">' + capture(&block) + '</span>'
    end
  end
end

我在我的视图中使用它,如下所示:

<% field_with_error @some_object, :assoc do %>
  <%= f.select(:assoc_id, @associations.collect {|assoc| [ asoc.name, assoc.id ] }) %>
<% end %>

如果有人知道更好或更清洁的方法,我愿意接受建议。

于 2009-04-25T11:34:11.307 回答
2

我发现这篇博客文章似乎解决了这个问题:

http://blog.invalidobject.com/2007/09/16/rails-error-wrapping-for-select-input-fields-of-referenced-models

希望对您有所帮助!

于 2009-04-14T14:13:51.903 回答
1

这就是我解决这个问题的方法。

我创建了一个特定的“field_with_errors”选择包装器:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
   if html_tag =~ /^<input/
     %{<div class="field_with_errors">#{html_tag}<label for="#{instance.send(:tag_id)}" class="message">#{instance.error_message.first}</label></div>}.html_safe
   elsif html_tag =~ /^<select/
 %{<div class="field_with_errors" id="select-error">#{html_tag}</div>}.html_safe
   else
     %{<div class="field_with_errors">#{html_tag}</div>}.html_safe
   end
end

CSS:

#select-error {
    border: 1px solid red;
    overflow-y: auto;
    overflow-x: hidden;
}

我将验证修改为 :whatever_id 而不是:whatever

validates :whatever_id, :presence => true

我忘记了,选择:

f.collection_select(:whatever_id, Whatever.all, :id, :name, prompt: t(:please_choose))
于 2012-02-14T14:00:30.923 回答
0

另一种方式,可以在方法或控制器级别或在 environment.rb 中插入:

ActionView::Base.field_error_proc = proc { |输入,实例| 输入 }

于 2009-08-11T20:56:39.100 回答