棘手的活跃记录关系 – 多态双向自我指涉

您如何对出版物(文章,书籍,章节等)的引用和引用进行建模?

出版物可以是文章,书籍或章节,它有许多参考其他出版物和其他出版物参考它(称这些引用)

我需要能够列出出版物之间的关系:出版物中的参考文献以及其他出版物对本出版物的引用

我最初的理解是,这将是处理不同类型的出版物的多态关系,并且它需要双向自联接。

我刺伤了它

Publication belongs_to :writing, :polymorphic =>true has_and_belongs_to_many :references :class_name => "Publication" :join_table => 'reference_citation' :foreign_key => 'reference_id' :foreign_key => 'citation_id' Book, Chapter, Article all have: has_many :publications :as =>writing 

我发现这有点令人困惑,所以任何有助于澄清它的建议都会很棒。 甚至是对象和字段命名建议。

[我在这里问了一个不太清楚的问题。]

我也可能需要使用很多通过因为我需要能够破坏关系

这是使用单表inheritance使用自引用关系的解决方案。 使用以下命令创建应用程序:

 $ rails myproject $ cd myproject $ script/generate model publication type:string name:string $ script/generate model citation publication_id:integer reference_id:integer 

以这种方式设置关系:

 class Publication < ActiveRecord::Base has_many :citations has_many :cited_publications, :through => :citations, :source => :reference has_many :references, :foreign_key => "reference_id", :class_name => "Citation" has_many :refered_publications, :through => :references, :source => :publication end class Citation < ActiveRecord::Base belongs_to :publication belongs_to :reference, :class_name => "Publication" end class Article < Publication end class Book < Publication end class Chapter < Publication end 

现在我们可以创建数据库并从控制台中尝试:

 $ rake db:migrate $ script/console Loading development environment (Rails 2.2.2) >> a = Article.create!(:name => "Article") => #
>> b = Book.create!(:name => "Book") => # >> a.citations.create(:reference => b) => # >> a.citations => [#] >> a.references => [] >> b.citations => [] >> b.references => [#] >> a.cited_publications => [#] >> a.refered_publications => [] >> b.cited_publications => [] >> b.refered_publications => [#
]

这是一个不使用单表inheritance的解决方案。 这意味着有文章,书籍和章节表,而不是一个出版物表。 以下是运行以创建应用程序的命令:

 $ rails myproject $ cd myproject $ script/generate model book name:string $ script/generate model chapter name:string $ script/generate model article name:string $ script/generate model citation publication_type:string publication_id:integer reference_type:string reference_id:integer 

lib/acts_as_publication.rb创建此文件:

 module ActsAsPublication def self.included(base) base.extend(ClassMethods) end module ClassMethods def acts_as_publication has_many :citations, :as => :publication has_many :references, :as => :reference, :class_name => "Citation" end end end 

config/initializers/acts_as_publication.rb创建此文件:

 ActiveRecord::Base.send(:include, ActsAsPublication) 

然后在每个模型,文章,书和章中调用,如下所示:

 class Article < ActiveRecord::Base acts_as_publication end 

然后在app/models/citation.rb添加这些关系:

 class Citation < ActiveRecord::Base belongs_to :publication, :polymorphic => true belongs_to :reference, :polymorphic => true end 

现在我们可以创建数据库并从控制台中尝试:

 $ rake db:migrate $ script/console Loading development environment (Rails 2.2.2) >> a = Article.create!(:name => "a") => #
>> b = Article.create!(:name => "b") => #
>> Citation.create!(:publication => a, :reference => b) => # >> a.citations => [#] >> a.references => [] >> b.citations => [] >> b.references => [#] >> Book.create!(:name => "foo") => # >> a.citations.create(:reference => Book.first) => # >> Book.first.references => [#] >> a.citations => [#, #]

我在http://github.com/francois/so-536261/tree/master上有一个不完整的答案

基本上,DB模式确实支持您的用例,但ActiveRecord不支持。 该解决方案可能涉及使用find或sql或其他技巧。