【问题标题】:Ruby on Rails: polymorphic many-to-many design?Ruby on Rails:多态多对多设计?
【发布时间】:2026-01-16 15:40:02
【问题描述】:

我无法让多态多对多模型在 ruby​​/rails 中工作。该模型有三个需要连接的表,Infection、Drug、Symptom:

create_table "diseases" do |t|
    t.string     "name"
end

create_table "drugs" do |t|
    t.string     "name"
end

create_table "symptoms" do |t|
    t.string     "name"
end

create_table "to_symptoms" do |t|
    t.integer    "symptom_id"
    t.integer    "symptomatic_id"
    t.string     "symptomatic_type"
end

症状与感染和药物有关。棘手的部分是症状与药物的关系可能是副作用,也可能是禁忌症。我尝试这样做的方式是:

class ToSymptom < ActiveRecord::Base
    belongs_to :symptomatic, :polymorphic => true    
    belongs_to :symptom
end

class Drug < ActiveRecord::Base
    has_many :to_symptom, :as => :symptomatic

    has_many :contraindications, :class_name => "Symptom", 
             :through => :to_symptom, :source => :symptomatic, 
             :source_type => 'Contraindication'
    has_many :side_effects, :class_name => "Symptom", 
             :through => :to_symptom, :source => :symptomatic, 
             :source_type => 'SideEffect'
end

class Symptom < ActiveRecord::Base
    has_many :to_symptom

    has_many :diseases, :through => :to_symptom, :source => :symptomatic, 
             :source_type => 'Disease'
    has_many :contraindicated_drugs, :class_name => "Drug", 
             :through => :to_symptom, :source => :symptomatic,
             :source_type => 'Contraindication'
    has_many :caused_by, :class_name => "Drug", :through => :to_symptom, 
             :source => :symptomatic, :source_type => 'SideEffect'
end

class Disease < ActiveRecord::Base
    has_many :to_symptom, :as => :symptomatic
    has_many :symptoms, :through => :to_symptom
end

疾病 症状关系似乎按我预期的方式运作,但药物和症状之间的关系并没有达到我的预期。症状->药物方向的关系似乎起作用,但相反的方向会产生一些奇怪的 SQL。如果我尝试类似:

d = Drug.first
d.contraindications

我会得到以下 SQL:

SELECT 
    `symptoms`.* 
FROM `symptoms` 
INNER JOIN `to_symptoms` ON `symptoms`.`id` = `to_symptoms`.`symptomatic_id` 
WHERE `to_symptoms`.`symptomatic_id` = 2 
    AND `to_symptoms`.`symptomatic_type` = 'Drug' 
    AND `to_symptoms`.`symptomatic_type` = 'Contraindication'

to.symptoms.symptomatic_type = drug 不应该在其中,并且在 to_symptoms 的错误字段上加入(symptomatic_idsymptom_id。我尝试了很多不同的组合,但我可以'似乎无法让这个工作。我正在尝试做的事情在 RoR 中是否可行?

【问题讨论】:

    标签: ruby-on-rails activerecord many-to-many polymorphic-associations


    【解决方案1】:

    这似乎并没有被广泛宣传,但它显然在 Rails 中不起作用......(多态 mas_many :through)(至少不是没有疯狂的黑客攻击)。我会尝试找到一些支持链接

    【讨论】:

    • 嗯,这可以解释为什么我找不到任何在线工作的例子。我可以通过定义诸如`def contraindications Symptom.joins(:to_symptom).where(:to_symptoms => {:symptoms_id => self.id, :symptom_type => 'Contraindication'}) end`之类的函数来绕过访问这些函数,但它会有一种更快的方式来建立这些联系仍然很高兴。你能给我任何提示来重载 d.contraindications << Symptom.create(...) 这样的东西就可以工作了吗?或者我需要创建一个类禁忌症才有机会吗?再次感谢!
    • 超载运算符 :strugglingwithruby.blogspot.com/2010/04/… 页面底部显示了“