通过单个查询中的自联接获取has_many的所有子项

时间:2014-08-22 17:40:30

标签: sql ruby-on-rails activerecord associations

我的图书馆里满是文章。一篇文章通过引文引用其他文章。所以它通过引用自我引用,如下:

class Article < ActiveRecord::Base
  has_many :citations
  has_many :referenced_articles, through: :citations
end

class Citation < ActiveRecord::Base
  belongs_to :Article
  belongs_to :referenced_article, :class_name => "Article"
end

问题: 在给定一些文章的情况下,我如何获取所有引用的文章:直接引用并间接引用其引用的文章等,直到达到没有任何引用的文章(在我的情况下可能不会更多)超过15级。)

我目前的方法: 鉴于一些文章&#34; main_article&#34;,我可以通过

获得它的reference_articles
sub_articles = main_article.referenced_articles

我更深入一级:

sub_articles = Article.eager_load(:referenced_articles).where(id: sub_articles)
sub_sub_articles = sub_articles.collect {|x| x.referenced_articles}.flatten

将它放在循环中会得到所需的结果,每次迭代都会更深一层。 但我希望有一个更好的解决方案,因为我目前正在拿每篇文章两次。

边界条件:我不想在我的图书馆的每篇文章中添加引用实例,告诉它在哪里使用(引用)。所以我猜这个祖先&#39;宝石不是一种选择:(

1 个答案:

答案 0 :(得分:0)

我没有任何递归查询的经验,但如果您的数据库引擎支持它们,您可能希望查看带递归的common-table-表达式:

http://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL#Common_table_expression

Oracle,sqlserver和postgres似乎都支持递归cte。

你可能不得不为此自己制作原始sql,我怀疑你会在rails中找到很多支持,只需一个查询即可。