我不明白这两种关联类型的区别。
例如,我们有2个表:
拳击手
[ id, name, title ]
标题
[ id, name ]
因此,我们可以这样指定我们的关联:
boxer.rb
belongs_to :title, forign_key: "title"
然后像Boxer.find(1).title.name
一样使用它从逻辑上讲,每个拳击手总是有一个标题记录,每个标题都有很多拳击手。
那么为什么我们不指定has_one
和has_many
关系?当我指定belongs_to :title, forign_key: "title"
时,这意味着在我的情况下FK指向桌上拳击手( boxer.rb )。但是当我尝试编写has_one :title, forign_key: "title"
时,它会在title
表中搜索列titles
。为什么呢?
答案 0 :(得分:3)
将具有外键索引的模型上的belongs_to
放入另一个模型中。在另一个模型上,您放置has_one
。两者都允许您覆盖fk列的名称,但它始终位于包含belongs_to
的表中。
我用这个技巧记住:
一只狗belongs_to
他的主人(而不是相反)和主人has_one
狗。狗用他的主人的号码穿着 id 标签,而不是相反。
答案 1 :(得分:0)
一般来说,如果您没有提及任何内容,请写下以下内容:
class Boxer < ActiveRecord::Base
belongs_to :title
end
然后你这样做:
boxer = Boxer.find_by_id(1)
puts boxer.title
boxer.title
;它进入titles
表,并在那里搜索一行,其中id
与存储在您调用方法boxer_id
的对象中的boxer.title
相同。 / p>
当您未在模型中指定foreign_key
时,就会这样做。
但是如果你确实指定了foreign_key
如下:
class Boxer < ActiveRecord::Base
belongs_to :title, foreign_key: 'title'
end
现在,在boxers
表中,必须有一列title
,用于存储其所属标题的id
。
不同之处在于:如果您未指定foreign_key
,它会查找title_id
,但是当您指定foreign_key
时,它会搜索该<%= f.select :category,
options_for_select(['drink','food','medicine','supplement','drug','ingredient','lifestyle','other'], params[:category]), {}, { :class => 'span3 controls controls-row' } %>
。
答案 2 :(得分:0)
我认为这种混淆可能源于你的模型之间的关联有点违反直觉。您说每个boxer
只有一个title
,但每个title
可能有多个boxers
,对吗?在这种情况下,虽然直觉上我们谈论属于拳击手的头衔,但你的联系实际上应该是另一种方式:每个冠军都有很多拳击手,每个拳击手都属于一个冠军。所以:
# title
has_many :boxers
# boxer
belongs_to :title
如果Rails中有has_one
或has_many
关联,则另一方必须始终拥有belongs_to
,这应该位于具有foreign_key到另一个表的模型上。从上面可以看出,Rails通常会假设boxers
表有一个名为title_id
的列,它对应id
titles
列中的值。鉴于您没有这样做,您需要提供其他信息,以便Rails可以正确处理关联。
具体来说,你需要告诉Rails Boxer模型使用title
作为外键,并且这对应于Title name
:
# title
has_many :boxers, primary_key: :name, foreign_key: :title
# boxer
belongs_to :title, foreign_key: :title
我建议改用更标准的设置,然后将title
字段放在拳击手上,而不是title_id
。它可能也值得一看RailsGuide on Active Record Associations,因为它具有很多关于这一切是如何工作的详细信息。