Ruby on Rails: способ доступа к информации в таблице связей с помощью ActiveRecord? - PullRequest
1 голос
/ 16 июля 2011

Есть ли встроенный метод для доступа к данным в таблице компоновщиков через среду ActiveRecord?У меня есть несколько таблиц, связанных через многие-многие соединения, где (в идеале) информация о ссылке должна храниться в таблице связей.

Например, у меня есть три таблицы

create_table :diseases do |t|
    t.integer id
    t.string  name
end

create_table :pathogens do |t|
    t.integer id
    t.string  name
end

create_table :disease_pathogens do |t|
    t.integer :disease_id,  :null => false
    t.integer :pathogen_id, :null => false
    t.float   :probability
end

С классами, определенными как

class Disease < ActiveRecord::Base
    has_many :disease_pathogen
    has_mahy :pathogens, :through => :disease_pathogens
end

class Pathogen < ActiveRecord::Base
    has_many :disease_pathogen
    has_many :disease, :through => :disease_pathogen
end

class DiseasePathogen < ActiveRecord::Base
    belongs_to :disease
    belongs_to :pathogen
end

Где таблица связей дает вероятность того, что болезнь была вызванапатоген.Есть ли способ получить эту информацию простым способом?Теперь, если у меня есть экземпляр Disease d, я могу найти связанный с ним вызов, вызвав d.pathogens.Есть ли простой способ получить значение вероятности для этих отношений?Мне бы понравился такой интерфейс, который делает чтение и запись этого атрибута более простым без необходимости написания специальных методов get_ и set_, тем более, что я знаю, что делать это в raw sql было бы просто.

Оченьидеальный интерфейс позволил бы взаимодействия в форме:

d = Disease.first
d.pathogens << Pathogen.create(:name => "xx", :probability => 0.12)
d.pathogens[0].probability

и тому подобное.Конечно, это должно было произойти раньше, но я не смог найти никакой информации об этом.Или, может быть, я просто пытаюсь сделать что-то, что выходит за рамки соглашений ruby?Спасибо за любую помощь!

Ответы [ 2 ]

1 голос
/ 16 июля 2011

Проблема в том, что probability, по крайней мере, в данном определении моделей, не является атрибутом Pathogen, и вы хотите получить к нему доступ, как если бы это было.

Попытка сделать что-то вроде d.pathogens << Pathogen.create(:name => "xx", :probability => 0.12) обычно не очень хорошая идея, потому что вы объединяете идею объекта DiseasePathogen в объект Pathogen. Либо эти две концепции являются достаточно отдельными, чтобы заслужить свои собственные классы моделей, либо это не так.

Если заболевания и патогенные микроорганизмы не имеют присущей им вероятности, то связь между ними явно важна сама по себе. Код будет отражать, что:

d = Disease.first
p = Pathogen.create(:name => 'xx')
l = DiseasePathogen.create(:disease => d, :pathogen => p, :probability => 0.12)

Последняя строка вашего идеального интерфейса имеет похожую проблему, но исправление немного сложнее.

Когда вы говорите d.pathogens[0], вы имеете в виду не отношение, а только конкретный объект Pathogen, который может принадлежать любому числу Disease объектов. Этот голый объект не может знать, на какую ссылку вы ссылаетесь. В этом весь смысл DiseasePathogen объектов.

Использование d.disease_pathogens[0].probability будет работать так, как вы хотели. В противном случае вы можете создать вспомогательную функцию в основных классах, которая предоставит хороший псевдоним этой функциональности.

Суть в том, что когда вы хотите сослаться на данные, хранящиеся в определенном объекте (в данном случае объект, связывающий два других объекта), вам необходимо как-то однозначно указать этот объект. Если вы не хотите этого делать, вам придется поместить нужные данные в один из других объектов.

Лучший способ, которым я могу придумать для имитации желаемого интерфейса, - это пользовательская функция в Disease и Pathogen, которая принимает объект дополнительного класса и ищет желаемую вероятность.

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

Я могу думать только о:

p = d.disease_pathogens.where(:pathogen_id => d.pathogens[0].id).first.probability

Если вы включите его в функцию, он не будет выглядеть слишком плохо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...