简体   繁体   English

通过一次查询中的自我连接获取has_many的所有子级

[英]Get all children of has_many through self-join in single query

I am having a library full of Articles. 我的图书馆里满是文章。 An article references other articles through citations. 一篇文章通过引用引用了其他文章。 So it's self-referencing through citations, like this: 因此,它是通过引用进行自我引用,如下所示:

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

The question: How can I, given some article, fetch all citated articles: both directly citated and indirectly citated by it's referenced articles, etc. until reaching the articles that do not have any citations (in my case that will probably be no more than 15 levels deep). 问题:给定某篇文章,我如何才能获取所有被引用的文章:被其引用的文章直接被引用或间接被引用等等,直到到达没有任何引用的文章(在我的情况下,可能不超过15级深)。

My current method: Given some article "main_article", I can get it's referenced_articles by 我当前的方法:给定一些文章“ main_article”,我可以通过以下方式获取它的referenced_articles

sub_articles = main_article.referenced_articles

And to go one level deeper I do: 为了更深入,我做了:

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

Putting this in a loop gives the desired result, going one level deeper every iteration. 将其放在一个循环中可以得到理想的结果,每次迭代都更深一层。 But i am hoping for a nicer solution, as I am currently fetching every article twice. 但是我希望有一个更好的解决方案,因为我目前每次获取两次文章。

Boundary condition: I don't want to add a referencing instance to every article in my library telling it where it is used(citated). 边界条件:我不想在我的库中的每篇文章中添加引用实例来告诉它在何处使用(引用)。 So I guess the 'ancestry' gem is not an option :( 所以我想'祖先'宝石不是一个选择:(

I don't have any experience with recursive queries, but if your database engine supports them you might want to look at common-table-expressions with recursion: 我对递归查询没有任何经验,但是如果您的数据库引擎支持它们,那么您可能希望使用递归查看common-table-expressions:

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

Oracle, sqlserver, and postgres all seem to support recursive cte's. Oracle,sqlserver和postgres似乎都支持递归cte。

You'll probably have to craft the raw sql for this yourself, I doubt you'll find much support in rails for doing this with a single query. 您可能必须自己为此编写原始sql,我怀疑您会在Rails中找到很多支持以单个查询来完成此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM