2010-05-11 2 views
2

이 내 모델입니다 :collection_select를 사용하여 다형 모델을 만드는 방법은 무엇입니까?

class Speaker < ActiveRecord::Base 
    belongs_to :session, :foreign_key => :session_id, :class_name => :Session 
    belongs_to :speakable, :polymorphic => true 
end 

class Session < ActiveRecord::Base 
    has_many :speakers 
    accepts_nested_attributes_for :speakers 
end 

class Person < ActiveRecord::Base 
    has_many :speakers, :as => :speakable 
end  

class Company < ActiveRecord::Base 
    has_many :speakers, :as => :speakable 
end 

내가 지금하고 싶은 것은이 같은 것입니다 : 응용 프로그램/조회/세션/edit.html.erb

<% f.fields_for :speakers do |sf| %> 
    <p> 
     <%= sf.label :speaker %><br /> 
     <%= sf.collection_select :speakable, Company.all + Person.all, :id, :full_name %> 
    </p> 
    <% end %> 

그러나이 때문에 작동하지 않습니다 다형성 할당. 이 문제에 어떻게 접근합니까?

편집 : 오류 : PARAMS의 존재와

undefined method `base_class' for String:Class 

:

"speaker"=>{"speakable"=>"1063885469", "session_id"=>"1007692731"} 

읽기 가능해 전달 값은 스피커/회사의 ID입니다. 예, 반환 할 값은 collection_select입니다.하지만 두 값 (speakable_idspeakable_type)을 모두 어떻게 관리 할 수 ​​있습니까?

+0

어떤 오류가 있습니까? – shingara

답변

0

두 가지 방법으로 해결했습니다.

첫 번째는 양식에서 컬렉션을 munge하는 것이므로 어떤 유형의 ID로 시작해야하는지 파악할 수 있습니다. 이 비슷한 : 당신의 컨트롤러 액션에서 다음


그리고는 :

def action 
    if params[:speaker][:speakable].begins_with?("Person:") 
    speak_type = 'Person' 
    speak_id = params[:speaker][:speakable].split(":")[1].to_i 
    elsif params[:speaker][:speakable].begins_with?("Company:") 
    speak_type = 'Company' 
    speak_id = params[:speaker][:speakable].split(":")[1].to_i 
    end 
    params[:speaker].delete(:speakable) 
    obj = Speaker.new(params[:speaker]) 
    obj.speaker_type = speak_type 
    obj.speaker_id = speak_id 
    ... rest of action ... 
end 

두 번째는 숨겨진 필드가있는 speakable_type 및 speakable_id 변경하는 자바 스크립트를 사용하는 것입니다 페이지에 숨겨져 있습니다. 이 필드를 채우기 위해 자동 완성기를 사용 했으므로 선택이 완료되었을 때 자바 스크립트를 호출하는 것은 충분히 쉬웠습니다. 두 번째 방법은 컨트롤러를 lot 클리너로 만듭니다.

+0

대단히 감사합니다. 이것은 매우 hackish이지만, 작동해야합니다 :-) – muxe

1

hidden_field을 사용하면 speakable_type을 저장할 수 있습니다. 이 방법을 사용하면 선택한 옵션이 변경 될 때마다 hidden_field의 값을 변경해야합니다. 나는 이것이 최선의 방법이라고 확신하지는 않지만 ...

희망이 있습니다.

편집

당신은 당신의 선택의 :onchange 옵션을 정의해야합니다.

<%= sf.collection_select :speakable, Company.all + Person.all, :id, 
    :full_name, {}, {:onchange => "setSpeakableType()"} %> 

hidden_fieldnil 값으로 시작됩니다.

<%= sf.hidden_field :speakable_type, :value => nil %> 

그리고 당신의 setSpeakableType() 기능은 적절한 speakable_type 설정해야합니다.

+0

답변 해 주셔서 감사합니다. 말하기 가능 항목을 선택해야하기 때문에 숨겨진 필드의 값을 어떻게 설정합니까? – muxe

+0

편집 내 답변 :] –

+0

나는 JS에별로 익숙하지 않으므로 jamuraa의 제안을 확인해 보겠다. 그러나 나는 당신의 접근 방식이 효과가 있다고 생각한다. – muxe

관련 문제