2

这是我的模型:

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  

我现在想做的是这样的:app/views/sessions/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 %>

但由于多态分配,它不起作用。我该如何解决这个问题?

编辑:错误是:

undefined method `base_class' for String:Class

参数为:

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

传递给 speakable 的值是发言人/公司的 id。是的,这是我指定collection_select要返回的值,但我怎样才能同时提供两个值 (speakable_idspeakable_type) ?

4

2 回答 2

1

您可以使用 ahidden_field来保存speakable_type. 这样,hidden_field每次所选选项更改时,您都必须更改值。我不确定这是最好的方法,但有效......

希望它可以帮助你。

编辑

您必须:onchange在您的选择中定义选项。

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

从价值hidden_field开始nil

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

而且您的setSpeakableType()功能必须设置正确的speakable_type.

于 2010-05-11T17:35:38.937 回答
0

我解决了这个问题的两种方法。

首先是在表单中调整您的集合,以便您可以确定 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

第二种是使用javascript更改隐藏在页面中的隐藏字段speakable_type和speakable_id。我最终使用自动完成器来填写此字段,因此在进行选择时调用 javascript 很容易。第二种方法使控制器干净。

于 2010-05-11T17:49:46.107 回答