2009-04-14 32 views
6

Hành vi bình thường không nhận được các thẻ lựa chọn arround chọn có các lỗi xác thực không? Cá nhân tôi không thấy lý do tại sao các thẻ được chọn phải được xử lý khác với các thẻ biểu mẫu khác (đầu vào, văn bản).Xác nhận Rails và thẻ chọn gói 'fieldWithErrors' bao gồm

I do nhận lỗi trong các phương thức error_messages_forerror_message_on cho trường đó.

PS. Tôi đã thay đổi một chút số ActionView::Base.field_error_proc để nhận thẻ span thay vì div, nhưng đó không phải là vấn đề.

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>" 
} 

Trả lời

2

Bởi vì tôi không thể tìm ra lý do tại sao các thẻ chọn không được bao gồm trong Proc đó, tôi tạo ra một phương pháp trợ giúp mà không có gì nhiều giống nhau.

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 

tôi sử dụng nó trong quan điểm của tôi như vậy:

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

Nếu ai biết một cách tốt hơn hoặc sạch hơn để làm điều đó, tôi mở để gợi ý.

2

tôi tìm thấy bài đăng blog mà dường như địa chỉ này:

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

Hy vọng nó sẽ là hữu ích!

+0

Xin chào. Cảm ơn vi đa trả lơi! Tôi cũng tìm thấy điều đó, nhưng anh ấy không thực sự xác định liệu anh ta có làm việc hay không. Có một liên kết đến wiki đường ray, nhưng nó bị hỏng. Tôi muốn tránh càng nhiều càng tốt thêm một thử nghiệm trên 'error_message_on' cho mỗi lựa chọn bởi vì điều đó thực sự sẽ làm phức tạp quan điểm của tôi. – andi

+0

Anh ta chỉ định cách làm cho nó hoạt động ở đây: "Giải pháp duy nhất là thay đổi xác thực trong mô hình working_time từ project thành project_id". Đó là, trong lớp mô hình, thay đổi "validates_presence_of: project" thành "validates_presence_of: project_id" –

0

Một cách khác, có thể được chèn vào phương pháp hoặc bộ điều khiển mức, hoặc trong environment.rb:

ActionView :: Base.field_error_proc = proc {| đầu vào, ví dụ | đầu vào}

4

Vấn đề (cho tôi ít nhất) là f.select :whatever_id tôi đang tìm kiếm trong đối tượng object.errors cho một chìa khóa của :whatever_id khi xác nhận tôi đã thực sự vào :whatever, không :whatever_id.

tôi làm việc xung quanh vấn đề này gây phiền nhiễu bằng cách thay đổi

object.errors.on(@method_name) 

để

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

Đây là diff (chống 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

Đây là cách tôi giải quyết vấn đề đó.

tôi tạo ra một cụ "field_with_errors" chọn wrapper:

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; 
} 

Và tôi sửa đổi kiểm chứng thực của tôi để: whatever_id thay vì : bất cứ điều gì

validates :whatever_id, :presence => true 

Tôi đã quên, chọn:

f.collection_select(:whatever_id, Whatever.all, :id, :name, prompt: t(:please_choose)) 
+0

Cảm ơn, tôi thấy nó có ích để sửa đổi nếu bao gồm một kiểm tra cho một lớp 'không có lỗi' trong html_tag, khi tìm thấy don không hiển thị bất kỳ lỗi nào cả. Rất tiện dụng khi một số trường biểu mẫu có những thứ như javascript datepickers trên đó mà đánh dấu thêm sẽ phá vỡ. – benz001

Các vấn đề liên quan