Ruby on rails 如何使用集合创建多态模型?

Ruby on rails 如何使用集合创建多态模型?,ruby-on-rails,forms,polymorphic-associations,Ruby On Rails,Forms,Polymorphic Associations,这是我的模型: 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 accep

这是我的模型:

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  
参数为:

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

传递给speakable的值是演讲者/公司的id。是的,这是我指定的
集合\u select
返回的值,但是我如何才能同时提供这两个值(
可说出的\u id
可说出的\u type
)?

您可以使用
隐藏的\u字段来保存
可说出的\u type
。这样,每次所选选项更改时,您都必须更改
隐藏\u字段的值。我不确定这是不是最好的方法,但它是有效的

希望对你有帮助

编辑

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

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

您的
setPeakableType()
函数必须设置正确的
speakable\u类型

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

第一种方法是在表单中填充集合,以便确定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就足够简单了。第二种方法使控制器成为一个批次清洁剂

谢谢你的回答。我如何设置隐藏字段的值,因为还必须选择可说出的字段?我不太擅长JS,所以我将检查jamuraa提出的建议,但我认为您的方法应该有效。非常感谢,这应该有效,尽管它非常粗糙:-)
<%= sf.collection_select :speakable, Company.all + Person.all, :id, 
   :full_name, {}, {:onchange => "setSpeakableType()"} %>  
<%= sf.hidden_field :speakable_type, :value => nil %>
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