Rails 3 - 复杂的activerecord查询/带子查询

时间:2011-08-01 16:47:19

标签: ruby-on-rails activerecord join

我有一个名为 actions 的简单历史记录表,类似于以下内容:

id | actionable_id | actionable_type | user_id
----------------------------------------------

表格的actionable_types可以是'comment','vote'或'submission',其actionable_id与每个相应表的主键有关。同样,所有评论和投票都属于提交。

此外,我有一个友谊表,类似于以下内容:

id | user_id | friend_id | user_id
----------------------------------

表的user_id属于拥有朋友的用户(friend_id是朋友)。

  

如果您还没有猜到,每当用户评论,投票或上传新提交时,它都会作为新的“操作”添加到历史记录表中。为单个用户的朋友获取所有操作是快速而直接的,并且到目前为止工作得非常好。但是,这不是我的问题......

     

我想获取属于当前用户的非朋友群组的所有评论和投票。此外,只有当前用户对同一提交内容进行了投票或评论时,才会选择对提交条目的评论和投票。

因此,我需要进行以下两个查询,假设current_user是当前登录的用户。

查询1 - 所有类型为vote的行为符合以下条件:

  • 他们属于current_user的非朋友
  • 他们不属于current_user
  • current_user至少有一个属于提交的投票(换句话说,如果投票属于此集合,则在集合之外至少存在一个投票,其vote.user_id = current_user.user_id)。 / LI>

查询2 - 符合以下条件的所有类型注释操作:

  • 他们属于current_user的非朋友
  • 他们不属于current_user
  • current_user至少有一条属于提交的注释(换句话说,如果注释属于此集合,那么集合之外至少存在一条注释,其comment.user_id = current_user.user_id)。 / LI>

由于两个查询都在同一个Action表中,因此对我来说理想的是只有一个查询(尽管我认为这是非常不可能的,因为需要大量的JOINS)。

我的主要挂断是与检查非友谊相关的子查询以及每个查询的最后一个条件(current_user至少有一个......)。我将免除你当前的查询代码库,因为它甚至可能不是很接近。

感谢您寻找&帮忙。

1 个答案:

答案 0 :(得分:0)

你想要一个复杂的查询。 这是我的建议(假设我已正确理解你的要求:

SELECT a.* FROM actions a
LEFT OUTER JOIN vote v
ON v.id=a.actionable_id AND a.actionable_type='vote'
LEFT OUTER JOIN comment c
ON c.id=a.actionable_id AND a.actionable_type='comment'
WHERE a.user_id<>current_user.id
AND NOT EXISTS (
  SELECT 1 FROM friendships f
  WHERE f.user_id=current_user.id
  AND f.friend_id=a.user_id
) AND EXISTS (
  SELECT 1 FROM submission s
  LEFT OUTER JOIN vote v1
  ON v1.submission_id=s.id
  LEFT OUTER JOIN comment c1
  ON c1.submission_id=s.id
  WHERE (v1.id IS NOT NULL
  AND v1.submission_id=v.submission_id
  AND v1.id<>v.id
  AND v1.user_id=current_user.id) OR
  (c1.id IS NOT NULL
  AND c1.submission_id=c.submission_id
  AND c1.id<>c.id
  AND c1.user_ud=current_user.id)
);

所以我抓住所有行动,加入对行动的投票和评论。 然后我过滤掉所有操作与我当前用户具有的user_id相同。 确保该操作不是朋友。 最后我得到提交的内容并加入current_users投票和对他们的评论,当提交的投票或评论存在时,这与所选操作的提交相同,那么我找到了非朋友用户的操作你在寻找。