2011-05-09 7 views
5

나는이 다음 모델 :억제 "기본은"속성

class Evaluation < ActiveRecord::Base 
    attr_accessible :product_id, :description, :evaluation_institutions_attributes 

    has_many :evaluation_institutions, :dependent => :destroy 
    accepts_nested_attributes_for :evaluation_institutions, :reject_if => lambda { |a| a[:token].blank? }, :allow_destroy => true  

    validate :requires_at_least_one_institution 

    private 

     def requires_at_least_one_institution 
     if evaluation_institution_ids.nil? || evaluation_institution_ids.length == 0 
      errors.add_to_base("Please select at least one institution") 
     end 
     end  
end 

class EvaluationInstitution < ActiveRecord::Base 

    attr_accessible :evaluation_institution_departments_attributes, :institution_id 

    belongs_to :evaluation 

    has_many :evaluation_institution_departments, :dependent => :destroy 
    accepts_nested_attributes_for :evaluation_institution_departments, :reject_if => lambda { |a| a[:department_id].blank? }, :allow_destroy => true 

    validate :requires_at_least_one_department 

    private 

    def requires_at_least_one_department 
     if evaluation_institution_departments.nil? || evaluation_institution_departments.length == 0 
     errors.add_to_base("Please select at least one department") 
     end 
    end 

end 

class EvaluationInstitutionDepartment < ActiveRecord::Base 
    belongs_to :evaluation_institution 
    belongs_to :department 
end 

내가 그렇게 내 양식이 중첩되어, EvaluationInstitution 및 EvaluationInstitutionDepartment에 대한 중첩 된 속성이 포함되어 평가의 형태를 갖는다 3 단계. 제 3 수준은 저에게 문제를주고 있습니다.

오류

예상대로 트리거하지만 오류가 requires_at_least_one_department에 대한 트리거 할 때 텍스트가

평가 기관 기지를 읽고있다하십시오 선택 적어도 하나의 부서 메시지는 "읽어야

하세요 적어도 하나의 부서를 선택하십시오 ".

"평가 기관베이스"는 어떻게 제거합니까? 초기화에 다음 원숭이 패치를 추가

+0

@Kevin에 대한 답변을 찾으셨습니까? 나는 똑같은 문제를 겪고있다. 질문을 간소화하면 도움이 될지 궁금해 ..? –

+0

답변을 찾지 못했습니다. – Kevin

+0

@paul, btw, 내 작업은 모든 유효성 검사를 상위 레벨 모델 평가로 밀어 넣는 것이 었습니다. 예를 들어 my : requires_at_least_one_department 함수가 평가 모델로 이동합니다. 대단한 해결책은 아닙니다. – Kevin

답변

6

Rails 3.2에서 full_message 메소드의 구현을 살펴보면 "% {attribute} % {message}"형식의 I18n을 통해 오류 메시지가 표시된다는 것을 알 수 있습니다.

그것은 다음과 같이 당신이 당신의 국제화 로케일의 표시 형식을 사용자 정의 할 수 있음을 의미한다 : 당신이 원하는대로 접두사 "평가 기관의 기본"을 제거 할

activerecord: 
    attributes: 
    evaluation_institutions: 
     base: '' 

.

+0

왜 내가 이것을 upvoted 모르겠다. 나는 이것을 작동시킬 수 없다. 그것은보기 흉하지 않은 해결책처럼 보였다. –

+0

로케일 파일의 두 번째 줄을 제거하여 작업하게했습니다 ... 즉, yaml 파일에 'errors'를 포함하지 마십시오. –

+0

제게는 복수형이 아닌 단수 형태로 로컬에서 모델 이름을 사용해야했습니다. 예 : evaluation_institution –

1

가 dynamic_form과 3.2.3에서 나를 위해 일을했다 :

class ActiveModel::Errors 
    #exact copy of dynamic_form full_messages except 'attr_name = attr_name.sub(' base', ':')' 
    def full_messages   
    full_messages = [] 

    each do |attribute, messages| 
     messages = Array.wrap(messages) 
     next if messages.empty? 

     if attribute == :base 
     messages.each {|m| full_messages << m } 
     else 
     attr_name = attribute.to_s.gsub('.', '_').humanize 
     attr_name = @base.class.human_attribute_name(attribute, :default => attr_name) 
     attr_name = attr_name.sub(' base', ':') 
     options = { :default => "%{attribute} %{message}", :attribute => attr_name } 

     messages.each do |m| 
      if m =~ /^\^/ 
      options[:default] = "%{message}" 
      full_messages << I18n.t(:"errors.dynamic_format", options.merge(:message => m[1..-1])) 
      elsif m.is_a? Proc 
      options[:default] = "%{message}" 
      full_messages << I18n.t(:"errors.dynamic_format", options.merge(:message => m.call(@base))) 
      else 
      full_messages << I18n.t(:"errors.format", options.merge(:message => m)) 
      end    
     end 
     end 
    end 

    full_messages 
    end 
end 

당신이 dynamic_form를 사용하지 않는 경우는, 다음 대신 시도 (양식 보석이 오류를 무시하지 않는 한. dynamic_form 같은 full_messages하는)을 수행합니다

attr_name = attr_name.sub(' base', ':') 
:

class ActiveModel::Errors   
    #exact copy of Rails 3.2.3 full_message except 'attr_name = attr_name.sub(' base', ':')' 
    def full_message(attribute, message) 
     return message if attribute == :base 
     attr_name = attribute.to_s.gsub('.', '_').humanize 
     attr_name = @base.class.human_attribute_name(attribute, :default => attr_name) 
     attr_name = attr_name.sub(' base', ':') 
     I18n.t(:"errors.format", { 
     :default => "%{attribute} %{message}", 
     :attribute => attr_name, 
     :message => message 
     }) 
    end 
end 

원래 코드의 유일한 변화는 다음과 같은 라인

제안을 환영합니다.

2

원숭이 패치가 필요하지 않은 솔루션을 찾고있는 사람이 있다면, 여기 내 오류 부분에서 한 일이 있습니다. 오류가있는 속성의 이름에서 "base"를 찾고, 존재하는 경우에만 메시지를 게시합니다. 그렇지 않으면 full_message를 작성합니다. 이름에 밑줄이있는 애트리뷰트가 있으면이 방법은 효과가 없지만이 방법은 효과가 없습니다. 조금 해킹 된 것이지만이 문제에 대한 다른 해결책도 있습니다.

<% if object.errors.any? %> 
    <div id="error-explanation"> 
    <div class="alert alert-error"> 
     <ul> 
     <% object.errors.each do |atr, msg| %> 
      <li> 
      <% if atr.to_s.include? "base" %> 
       <%= msg %> 
      <% else %> 
       <%= object.errors.full_message(atr, msg) %> 
      <% end %> 
      </li> 
     <% end %> 
     </ul> 
    </div> 
    </div> 
<% end %> 
+0

감사합니다. 나는 아주 비슷한 것을했다. (Rails 4) 그러나이 덜 해킹 된 체크로 : if ifr == : base || atr.to_s.ends_with? (". base")' –