ActiveRecord的查询联盟联盟、ActiveRecord

2023-09-08 15:41:53 作者:←+往事:通缉犯o_o

我已经写了几个复杂的查询(至少对我来说)与回报率的查询接口:

I've written a couple of complex queries (at least to me) with RoR's query interface:

watched_news_posts = Post.joins(:news => :watched).where(:watched => {:user_id => id})
watched_topic_posts = Post.joins(:post_topic_relationships => {:topic => :watched}).where(:watched => {:user_id => id})

这两个查询自己做工精细。两种方法都返回后的对象。我想这些职位合并成一个单一的ActiveRelation。因为有可能是岗位数十万在某些时候,这需要在数据库级别上完成的。如果它是一个MySQL查询,我可以简单地用户的 UNION 运营商。有谁知道我是否可以做同样的事情与回报率的查询界面?

Both of these queries work fine by themselves. Both return Post objects. I would like to combine these posts into a single ActiveRelation. Since there could be hundreds of thousands of posts at some point, this needs to be done at the database level. If it were a MySQL query, I could simply user the UNION operator. Does anybody know if I can do something similar with RoR's query interface?

推荐答案

根据橄榄的回答,我没有想出另一种办法解决这个问题。这感觉就像一个黑客一点,但它返回 ActiveRelation 的实例,这是我后摆在首位。

Based on Olives' answer, I did come up with another solution to this problem. It feels a little bit like a hack, but it returns an instance of ActiveRelation, which is what I was after in the first place.

Post.where('posts.id IN 
      (
        SELECT post_topic_relationships.post_id FROM post_topic_relationships
          INNER JOIN "watched" ON "watched"."watched_item_id" = "post_topic_relationships"."topic_id" AND "watched"."watched_item_type" = "Topic" WHERE "watched"."user_id" = ?
      )
      OR posts.id IN
      (
        SELECT "posts"."id" FROM "posts" INNER JOIN "news" ON "news"."id" = "posts"."news_id" 
        INNER JOIN "watched" ON "watched"."watched_item_id" = "news"."id" AND "watched"."watched_item_type" = "News" WHERE "watched"."user_id" = ?
      )', id, id)

我还是AP preciate它,如果任何人有任何建议,以优化这个或提高性能,因为它基本上是执行三个查询,感觉有点多余。

I'd still appreciate it if anybody has any suggestions to optimize this or improve the performance, because it's essentially executing three queries and feels a little redundant.