不获取包含验证错误的<div class="fieldWithErrors">
包装的arround选择标记是否正常?我个人认为没有理由为什么选择标签应该与其他表格标签(输入,textarea)区别对待。
我做在该字段的error_messages_for
和error_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>"
}
答案 0 :(得分:4)
问题(对我来说至少)是我的f.select :whatever_id
在object.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
答案 1 :(得分: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 %>
如果有人知道更好或更清洁的方式,我愿意接受建议。
答案 2 :(得分:2)
我发现这篇博文似乎可以解决这个问题:
希望它有用!
答案 3 :(得分: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而不是:无论
validates :whatever_id, :presence => true
我忘了,选择:
f.collection_select(:whatever_id, Whatever.all, :id, :name, prompt: t(:please_choose))
答案 4 :(得分:0)
另一种方法,可以在方法或控制器级别,或在environment.rb中插入:
ActionView :: Base.field_error_proc = proc {| input,instance |输入}