我有一个角色模型和一个链接模型。 Link模型表示从角色到另一个角色的链接。链接具有文本“描述”属性。从字符A到字符B的链接与从B到A的相反链接不同。字符与另一个字符有零个或一个链接。角色可以具有到不同角色的各种链接。字符可以通过各种不同的字符链接。
我使用了使用Active Record关系来部分实现Character和Link模型之间的关系:
class Character
has_many :links # the links from the character to other characters
class Link
belongs_to :character # the character from which starts the link to another character
它给了我有用的方法,比如character.links(从这个字符开始的所有链接的数组)或link.character(从中开始链接的字符)
链接模型还有一个to_character_id
,其中包含转到链接的角色的ID。因此,从字符A到字符B的链接是具有以下属性的实例:
character_id
=角色A的身份to_character_id
=字符B的ID description
=一些文字我编写了各种额外的方法,如character.links_to
(返回指向该字符的所有链接的数组)或link.to_character
(返回链接指向的字符),或{{1 (返回其他字符的数组,其中包含指向此字符的链接)。我还写了一个回调函数,以确保删除一个字符时,删除所有转到该字符的链接(恢复时也是如此)。
是否可以使用额外的AR关系声明来为我提供这种额外的方法,这样我就不必自己写那些方法和回调了?
使用Rails的Agile Web开发在“使用模型作为连接表”一节中提供了一个解决方案,但是对于连接两个不同表的连接表。 在我的例子中,我的连接表链接连接单个表的记录,字符。
答案 0 :(得分:3)
has_and_belongs_to_many
不再使用了;我会改用has_many :through
。
class Character < ActiveRecord::Base
has_many :links, :dependent => destroy
has_many :characters, :through => :links
has_many :source_links, :class_name => "Link",
:foreign_key => "to_character_id", :dependent => :destroy
has_many :source_characters, :class_name => "Character",
:through => :destination_links
end
class Link < ActiveRecord::Base
belongs_to :character
belongs_to :source_character, :class_name => "Character",
:foreign_key => "to_character_id"
end
请注意:dependent => :destroy
选项 - 这些选项会在删除字符时删除链接。命名是正确的 - 从角色的角度来看,source_links
是到这个角色的链接。所以现在你可以这样做:
@character.characters # characters I link to
@character.links # links I have to other characters
@character.source_characters # characters that link to me
@character.source_links # links other characters have to me
答案 1 :(得分:2)
我认为您需要以下内容:
class Character < ActiveRecord::Base
has_many :outbound_links, :class_name => "Link", :foreign_key => "from_character_id"
has_many :inbound_links, :class_name => "Link", :foreign_key => "to_character_id"
end
class Link < ActiveRecord::Base
belongs_to :from_character, :class_name => "Character", :foreign_key => "from_character_id"
belongs_to :to_character, :class_name => "Character", :foreign_key => "to_character_id"
end
您可以在http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
上阅读有关ActiveRecord关联的所有选项答案 2 :(得分:0)
我认为你真正想要的是使用连接表的自我参照HABTM关系
所以,如果你有一个联接表
create_table :character_links do |t|
t.integer :character_id
t.integer :linked_character_id
t.timestamps #if you want to know when the relationship was created
end
然后你会
class Characters < ActiveRecord::Base
has_and_belongs_to_many :linked_characters,
:class_name => "Characters",
:join_table => :character_links,
:foreign_key => "character_id",
:associated_foreign_key => "linked_character_id"
如果您需要传出链接和传入链接,那么您可以这样做
class Characters < ActiveRecord::Base
has_and_belongs_to_many :outgoing_links,
:class_name => "Characters",
:join_table => :character_links,
:foreign_key => "character_id",
:associated_foreign_key => "linked_character_id"
has_and_belongs_to_many :incoming_links,
:class_name => "Characters",
:join_table => :character_links,
:foreign_key => "linked_character_id",
:associated_foreign_key => "character_id"
刚刚切换了foreign_key和associated_foreign_key
这使您无需拥有单独的链接模型
这是航空代码(未经测试)