繁体   English   中英

将一些 SQL 查询转换为活动记录

[英]Convert some SQL query to active record

所以,我有这个“高级”查询(实际上并不多),我想将它翻译成 Ruby Active Record 的语法。

SELECT microposts.* 
FROM microposts
WHERE user_id IN 
      ( SELECT r.followed_id as uid 
        FROM relationships r 
        WHERE follower_id = 1 
      UNION 
        SELECT u.id as uid 
        FROM users as u 
        WHERE id = 1
      ) 
ORDER BY microposts.created_at DESC

这个想法是检索用户 1 和用户 1 按照创建顺序关注用户的所有微博,但我真的不知道如何使用 Active Record 的语法轻松翻译它。

任何想法 ?

PS:这里问的是一些 Rails 上下文:

我有 3 个模型: MicropostsUsersRelationships

  • 关系是处理所有用户关系(关注者/被关注者)的连接表。
  • 用户通过关系有很多follow_users/followers。
  • 用户有许多微圈,而微圈只有一个用户。

谢谢。

您的查询非常具体,因此最好的办法是使用 SQL 编写其中的很大一部分,或者尝试使用像squeel这样的 gem,它可以帮助从 ActiveRecord 生成非常定制的 SQL。

尽管如此,这应该可以在没有额外宝石的情况下完成工作:

user_id = ... #Get the user_id you want to test
Micropost.where("user_id IN 
  ( SELECT r.followed_id as uid 
    FROM relationships r 
    WHERE follower_id = ? )
  OR user_id = ?
  ", user_id, user_id).order("created_at desc")

不知道 Ruby,但 SQL 可以简化为:

SELECT microposts.* 
FROM microposts
WHERE user_id IN 
      ( SELECT r.followed_id as uid 
        FROM relationships r 
        WHERE follower_id = 1 
      ) 
   OR user_id = 1
ORDER BY microposts.created_at DESC

我的回答将假设(因为您在原始 SQL 查询之外没有提供 ruby​​/rails-context)您有一个User模型,一个通过关系:micropostsMicropost模型,以及通过关系:following一个Relationship模型。 User有许多相关的MicropostRelationship实例。 你可以做

u = User.find(1)
user.microposts + user.following.microposts

或者您可以将其移动到Micropost的方法中

def self.own_and_following(user)
  user.microposts + user.following.microposts      
end

并调用Micropost.own_and_following(User.find(1))

这可能不是您要查找的内容,但考虑到您在 Rails 应用程序中的上述可能关系,听起来应该可以使用类似的方法。

我设法只使用 where 来做到这一点,对我来说似乎很像 find_by_sql,我不知道哪个更好:

Micropost.order('created_at DESC').
where('user_id in (select r.followed_id as uid from relationships as r where follower_id = ?) or user_id = ?', user.id, user.id)

不知道这有多好,但它似乎有效。

暂无
暂无

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

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