2010-02-27 5 views
2

두 가지 모델, 앨범과 트랙이 있습니다. 앨범에는 많은 트랙이 있고 트랙은 앨범에 속합니다.다중 모델 양식에서 error_messages_for를 사용하는 방법은 무엇입니까?

앨범을 만들 때 필요한만큼 많은 트랙을 만들 수 있습니다. railscasts episode 197과 같습니다. railscasts 에피소드와 달리 트랙 양식에는 제목과 설명이 모두 포함되어 있습니다. 둘 다 필요합니다.

은 지금 형태는 다음과 같습니다

Create New Album 

Name: [  ] 

    Track (remove link) 
      Name:  [  ] 
      Description: [  ] 

    Track (remove link) 
      Name:  [  ] 
      Description: [  ] 

(add track link) 

나는 빈 양식을 제출하기로 결정하면, 나는 양식의 상단에 다음과 같은 오류 메시지가 얻을 :

Description can't be blank 
Title can't be blank 
Title can't be blank 

이러한 오류를 메시지는 모델에 한정되지 않고 페이지 상단에 있으며 각 모델에 대해 한 번만 나타납니다. 필드를 비워 두어 모두 비어 있으며 오류 메시지는 한 번만 표시됩니다 (특정 트랙과 관련 없음) .


초기 트랙 필드를 생성하려면, 내 album_controller의 새로운 액션에 다음 줄을 추가 :

<% form_for @album do |f| %> 
<%= f.error_messages %> 

<%= f.label :title %><br /> 
<%= f.text_field :title %> 

<% f.fields_for :tracks do |f, track| %> 
    <%= render :partial => 'tracks/fields', :locals => {:f => f} %> 
<% end %> 

<%= f.submit "Submit" %> 
<% end %> 

: 2.times { @album.tracks.build }

내 양식이 어떻게 생겼는지의 요점은 이것이다 나는 <%= f.error_messages %><%= error_messages_for @album %> (앨범의 메시지 만 표시)으로 바꾸고 (각 트랙의 오류 메시지를 표시하기 위해) <%= error_messages_for track %>을 추가하려고 시도했지만 트릭을하지는 않습니다. 누구에게이 접근 방법을 알고 있습니까?

감사합니다.

답변

3

부모 개체와 자식 개체에 대한 오류 메시지를 구분하려면 약간 복잡 할 수 있습니다. 부모 객체를 저장하면 자식 객체의 유효성을 검사하기 때문에 자식 객체에 오류가 있습니다.

<% form_for @album do |f| %> 
<%= custom_error_messages_helper(@album) %> 

<%= f.label :title %><br /> 
<%= f.text_field :title %> 

<% f.fields_for :tracks do |t| %> 
    <%= t.error_messages message => nil, :header_message => nil %> 
    <%= render :partial => 'tracks/fields', :locals => {:f => t} %> 
<% end %> 

<%= f.submit "Submit" %> 
<% end %> 

또는 (가 혼란 때문에 t에 내가 이름 폼 빌더 객체 형태 f)는 t.error_messages 부분 'tracks/fields'에 함께이 줄을 넣을 수 있습니다 : 그래서 당신은 같은 것을 할 수 있습니다. 특정 자식 개체에 대한 오류 만 표시합니다 (어떤 제목 오류가 어떤 개체인지 확인할 수 있도록).또한 레일이보기 자동 CSS에 추가 예에 오류가 필드에 CSS 클래스 fieldWithErrors를 추가 할 것을 염두에 두어야 : @album.errors도 자식 개체에 대한 오류를 포함하고 있기 때문에 부모 개체에 대한 오류와

.fieldWithErrors { 
    border: 1px solid red; 
} 

은 더 복잡하다.

def custom_error_messages_helper(album) 
    html = "" 
    html << '<div class="errors">' 
    album.errors.each_error do |attr, error| 
    if !(attr =~ /\./) 
     html << '<div class="error">' 
     html << error.full_message 
     html << '</div>' 
    end 
    end 
html << '</div>' 
end 

그것은 모든 오류를 건너 뜁니다 : 내 생각이 그것을 처리하기 위해 사용자 지정 도우미를 작성했다, 그래서 나는 약간의 오차가 제거하거나 부모 개체와 associatted 만 오류를 표시 할 수있는 좋은 간단한 방법을 찾을 수 없습니다 그 속성은 이름 conatins '.' - 부모 객체와 관련된 모든 오류를 출력해야합니다. 유일한 문제는 기본에 추가 된 오류 때문입니다. 값이 base이고 부모 개체의 오류에 자식 개체에 추가 된 오류가 어떻게 추가되는지 잘 모르겠습니다. 아마도 그들은 attr 값도 base이므로이 도우미에 인쇄됩니다. 그러나 add_to_base을 사용하지 않으면 문제가되지 않습니다. 아래의 코드로, 위의 유사하지만

+0

테스트를 거치지 않았지만 종합적인 답변을 해주셔서 대단히 감사합니다! –

+0

레일즈 2.3.5에서 테스트했고 광고 된대로 작동합니다;) – klew

0

시도해 보셨습니까?

<% f.fields_for :tracks do |f, track| %> 
    <%= error_messages_for "track" %> 
    <%= render :partial => 'tracks/fields', :locals => {:f => f} %> 
<% end %> 
+0

yeup을! 그러나 양식 오류는 나타나지 않습니다. 루비 오류도 없습니다 ... 유효하지만 작동하지 않는 것 같습니다. –

+0

예 -이 문제는 페이지에'@track' 또는'@ album.track'이라는 변수가 없습니다 (이것은' error_messages_for'가 찾습니다) 대신'@ album.tracks'을 얻었습니다. –

+0

어떻게 해결할 수 있습니까? 트랙을 반복하고 있기 때문에 'track'이라는 인스턴스가 있지만 '@ track'이 아닌 (@ 기호가없는) 인스턴스가 있습니다. 나는 더 많은 반응을 장려하는 현상금을 시작할 것이고 당신이 올바른 길에 있다면 그것을 가질 수 있습니다;) 고마워요! –

1

먼저 f와 f는 범위를 혼동스럽게합니다. section_for 섹션에 "g"또는 무언가를 사용하면 범위를 이해할 수 있습니다.

는 그런 시도 : 앨범 모델에 accepts_nested_attributes_for :tracks

<% form_for @album do |f| %> 
    <%= f.error_messages %> 

    <%= f.label :title %><br /> 
    <%= f.text_field :title %> 

    <% f.fields_for :tracks do |g, track| %> 
    <%= g.error_messages -%> 
    <%= render :partial => 'tracks/fields', :locals => {:f => g} %> 
    <% end %> 

    <%= f.submit 'Create' %> 
<% end %> 

사용이.

본인은 직접 테스트를했으며 작동합니다. 개별 트랙의 오류가 트랙 섹션에 나타납니다.

저는 최신 버전의 레일즈를 사용하고 있습니다.

+0

특정 양식이 아닌 전체 양식 (상위 양식 포함)에 대한 오류 메시지를 표시합니다. 찾고). –

+0

예제 프로젝트로 테스트 해봤는데 정상적으로 작동합니다. 차이를 만드는 것은 "g"입니다. –

+0

... 그리고 아마도 사용중인 레일 버전 : –

0

, 내가 오류에 대한 객체의 객체 또는 배열을 테스트 할 수 있습니다

<%= show_errors([@company, @estabs], :header_ref => 'Company') %> 

def show_errors(objarray, opt) 

    return '' if objarray.blank? 

    err = [ ] 
    html = "" 

    objarray.each { |obj| 
      if obj.is_a?(Array) 
       obj.each { |oo| html << show_errors([oo], opt) } 
      elsif (obj.errors.count > 0) 
       err << obj.errors.full_messages #didnt worked with gem i18n 0.5.0 
      end 
       } 

    return '' if (err.count==0) and (html.blank?) 

    if err.count > 0 
     err.flatten!   #remove sub-arrays 
     err.each { |x| x.strip! } #strip:remove espaces 
     err.uniq!    #remove duplicated messages 
     err.sort! 

     header_ref = opt[:header_ref].nil? ? "" : opt[:header_ref] 

     erro_str = (err.count == 1) ? 'erro' : 'erros' 
     erro_verb = (err.count == 1) ? 'ocorreu' : 'ocorreram' 

     html << '<div class="erros" id="erros"> ' 
     html << "<b> #{header_ref}: #{err.count.to_s} #{erro_str} #{erro_verb}: </b> " 
     html << '<ul> ' 

     err.each { |e| html << '<li> ' + e + ' </li>' } 

     html << '</ul> </div>' 
    end 
    return html 
end 
관련 문제