我已经阅读了Rails网站上的Choosing Between has_many :through
and has_and_belongs_to_many
,但是我有点困惑,因为我对网站上提供的案例有所不同。
我有两个模型:Prop
和CharacterCostume
,角色的服装可以有多个与之关联的道具,但道具不属于该角色,任何数字都可以使用场景中的角色也是如此。
现在我的has_and_belongs_to_many :props
模型中有CharacterCostume
,它完全符合我的要求:它使用名为character_costumes_props
的表格获取与服装相关的所有道具我打电话给CharacterCostume#props
然而,由于“属于很多”部分,协会名称让我失望。服装不属于任何道具,因此has_and_belongs_to_many :character_costumes
模型中没有Prop
。
我知道没有它就可以正常运行,但它让我想到也许我应该使用has_many :through
关联,但这需要我创建一个多余的模型(它是多余的,对吧?)模型看起来像这样:
class CharacterCostumeProp < ActiveRecord::Base
belongs_to :character_costume
has_one :prop
end
此外,has_one
代替belongs_to
会在这里工作吗?
我希望代码尽可能保持语义,但我不确定这是否会增加资源需求或以某种方式降低性能,因为有一个中间模型。
这两种方法都有某些怪癖/好处吗?我的足够好吗?或者我的想法完全错误,我需要做什么?
谢谢!
答案 0 :(得分:2)
在HABTM和has_many :through
之间做出决定时,您必须问自己的一个最重要的问题是:
我是否要存储特定于该关联的任何信息?
读者和杂志之间的多对多关系可能被设想为HABTM或has_many :through
。但是,后者在这种情况下更有意义,因为我们可以很容易地想到我们可能想要存储的关联特定信息。
读者通过订阅与杂志相关,每个订阅都可以通过价格,开始日期,发行频率以及是否有效等字段来描述。
现有Tag
模型与Article
模型之间的关系显然属于多对多模式。一个特定标签与任何特定文章相关联的事实必然不会影响相同标签是否能够在未来与其他文章类似地关联。
但是,与前面的示例不同,这里关联本身就是我们需要的所有信息。我们只需要知道哪些标签与任何给定的文章相关联。协会何时成立并不重要。它持续多久并不重要。
对我们来说,与标签相关联的文章数量可能很重要。但是该信息存储在Tag
模型中,因为它不是特定于关联的。甚至还有一个Rails功能可以处理名为counter_cache
。
答案 1 :(得分:2)
我认为你想使用:has_many, :through
因为你想要直接使用关系模型 - 什么场景,消耗或损坏等等。
但是,它让你觉得有趣的原因是,has_many
和belongs_to
在很大程度上并不代表它们在英语中的含义。他们真正的含义分别是“他们有外键”和“我有外键”;例外是:dependent => :destroy
行为。
这仍然对has_and_belongs_to_many
没有帮助,因为你当时说,“他们有外键,我有外键` - 除了你可以想到它有点像添加一个新的对于“I”和“他们”而言,它们恰好是每个人的相同部分,并且具有这些键。
这有帮助吗?
答案 2 :(得分:0)
has_one
不起作用,您需要belongs_to
见下面的例子
class Student
has_and_belongs_to_many :courses
has_many :teachers, through: :courses
end
class Teacher
has_many :courses
has_many :students, through: :courses
end
class Course
has_and_belongs_to_many :students
belongs_to :teacher
def boring?
teacher.name == 'Boris Boring'
end
end
在上面的例子中,我使用了这两个版本。看看课程将如何拥有自己的逻辑?看看CourseStudent的课程怎么可能没有?这就是它归结为什么。好吧,对我而言。只要我无法为我的关联模型提供正确的名称和/或模型不需要额外的逻辑或行为,我就会使用has_many through
。