Ruby on Rails: полиморфный дизайн «многие ко многим»? - PullRequest
2 голосов
/ 17 июля 2011

У меня проблемы с получением полиморфной модели «многие ко многим», работающей в ruby ​​/ rails.Модель имеет три таблицы, которые необходимо объединить: Инфекция, Наркотики и Симптом:

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_id против symptom_id. Я пробовал кучу разных комбинаций, но, похоже, не могу заставить эту работать. Это то, что я пытаюсь сделать, даже возможно в RoR

1 Ответ

0 голосов
/ 17 июля 2011

Кажется, что это не очень широко рекламируется, но, очевидно, это не работает в Rails ... (полиморфный mas_many: through) (по крайней мере, без безумных хаков) Я постараюсь найти некоторые вспомогательные ссылки

...