开发者

Ruby on Rails: polymorphic many-to-many design?

I'm having troubles getting a polymorphic many-to-many model working in ruby/rails. The model has three tables that need to be joined, Infection, Drug, and 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

Where symptoms is linked to both infections and drugs. The tricky part is that the relationship of a symptom to a drug can be either as a side effect or as a contraindication. The way I tried to do this was:

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 => 'Contrai开发者_运维技巧ndication'
    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

The Disease <-> Symptom relationship seems to be working the way I'd expect, but the relationships between Drug and Symptom aren't doing what I'd expect. The relationship in the direction of symptoms-> drugs seems to be working, but the reverse direction generates some weird SQL. If I try something like:

d = Drug.first
d.contraindications

I'll get the following 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'

The to.symptoms.symptomatic_type = drug shouldn't be in there, and the join in on the wrong field of to_symptoms (symptomatic_id vs. symptom_id. I've tried a ton of different combinations, but I can't seem to get this one to work. Is what I'm trying to do even possible in RoR?


It seems that this isn't very widely advertised, but it apparently doesn't work in Rails... (polymorphic mas_many :through) (at least not without insane hacks). I'll try to find some supporting links

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜