Ruby on Rails:使用 ActiveRecord 访问链接表中的信息的方法?

发布于 2024-11-24 09:59:01 字数 1286 浏览 1 评论 0原文

是否有内置方法可以通过 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

,其中链接表给出了疾病由该病原体引起的概率。有没有一种方法可以直接获取这些信息?现在,如果我有一个疾病 d 的实例,我可以通过调用 d.pathogens 找到相关的实例。有没有一种简单的方法可以获取该关系的概率值?我喜欢这样的接口,使读取和写入该属性更加简单,而无需编写特定的 get_ 和 set_ 方法,特别是因为我知道在原始 sql 中执行此操作会很简单。

我非常理想的界面将允许以下形式的交互:

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

等等。当然,这肯定是以前出现过的事情,但我无法找到任何相关信息。或者也许我只是想做一些超出 ruby​​ 惯例的事情?感谢您的帮助!

Is there a built in method for accessing data in a linker table through the ActiveRecord framework? I have a number of tables linked through many-to-many connections, where (ideally) information about the link should be stored in the linkage table.

For example, I have the three tables

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

With classes defined like

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

Where the linkage table gives the probability that a disease was caused by that pathogen. Is there a way to get at that information in a straightforward way? Now, if I have an instance of Disease d, I can find the associated by calling d.pathogens. Is there an easy way to get at the value of probability for that relationship? I'd love an interface like that makes reading and writing that attribute a bit more straightforward without having to write specific get_ and set_ methods, especially since I know that doing it in raw sql would be straightforward.

My very ideal interface would allow interactions of the form:

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

and the like. Surely this has to be something that has come up before, but I haven't been able to find any information on it. Or maybe I'm just trying to do something that's outside of ruby's conventions? Thanks for any help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

喜你已久 2024-12-01 09:59:02

问题是,至少在给定的模型定义中,概率不是 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 对象。疾病对象。该裸露对象无法知道您所指的链接是什么。这就是 DiseasePathogen 对象的全部意义。

使用 d.disease_pathogens[0].probability 将按照您预期的方式工作。否则,您可以在主类中创建一个辅助函数,该函数将为该功能提供一个很好的别名。

最重要的是,当您想要引用存储在某个对象(在本例中是链接两个其他对象的对象)中存储的数据时,您需要以某种方式唯一地指定该对象。如果您不想这样做,则必须将所需的数据放置在其他对象之一中。

我能想出的模仿您想要的界面的最佳方法是 DiseasePathogen 中的自定义函数,它接受互补类的对象并查找所需的概率。

The problem is that probability, at least in the given definition of the models, is not an attribute of Pathogen and you want to access it as though it were.

Trying to do things like d.pathogens << Pathogen.create(:name => "xx", :probability => 0.12) is usually not a good idea because you're combining the idea of a DiseasePathogen object into a Pathogen object. Either the two concepts are separate enough to merit their own model classes, or they're not.

If diseases and pathogens do not have an inherent probability, then the link between them is clearly important in its own right. The code will reflect that:

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

The last line of your ideal interface has a similar problem, but the fix is a little more complex.

When you say d.pathogens[0], you're not referring to a relationship, but only to a specific Pathogen object that could belong to any number of Disease objects. That bare object has no way of knowing what link to which you're referring. That's the whole point of the DiseasePathogen objects.

Using d.disease_pathogens[0].probability will work the way you intended. Otherwise, you can create a helper function in the main classes that will provide a nice alias to this functionality.

The bottom line is that when you want to reference data stored in a certain object (in this case an object linking two other objects), you need to uniquely specify that object somehow. If you don't want to do that, you'll have to place the desired data in one of the other objects.

The best way I can come up with to mimic the interface you desire is a custom function in Disease and Pathogen that accepts an object of the complementary class and looks up the desired probability.

薯片软お妹 2024-12-01 09:59:02

我只能想到:

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

如果把它包装成一个函数,看起来也不会太糟糕。

I can only think of:

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

If you wrap it into a function, it won't look too bad.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文