简体   繁体   English

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

[英]Convert some SQL query to active record

So, I have this "advanced" query (not much, really) and I would like to translate it into Ruby Active Record's syntax.所以,我有这个“高级”查询(实际上并不多),我想将它翻译成 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

The idea was to retrieve all microposts for user 1 AND user 1 followed users in desc creation order, but I really don't know how to translate this easily using Active Record's syntax.这个想法是检索用户 1 和用户 1 按照创建顺序关注用户的所有微博,但我真的不知道如何使用 Active Record 的语法轻松翻译它。

Any thought ?任何想法 ?

PS : As asked here is some rails context : PS:这里问的是一些 Rails 上下文:

I have 3 models : Microposts , Users , Relationships .我有 3 个模型: MicropostsUsersRelationships

  • Relationships is a join table handling all users relationships (follower/followed stuff).关系是处理所有用户关系(关注者/被关注者)的连接表。
  • Users have many followed_users/followers through relationships.用户通过关系有很多follow_users/followers。
  • Users have many microhoops, and microhoops have one user.用户有许多微圈,而微圈只有一个用户。

Thanks.谢谢。

Your query is very specific, therefore your best bet would be to write a good portion of it using SQL, or try a gem like squeel that can help out generating very customized SQL from ActiveRecord.您的查询非常具体,因此最好的办法是使用 SQL 编写其中的很大一部分,或者尝试使用像squeel这样的 gem,它可以帮助从 ActiveRecord 生成非常定制的 SQL。

Nevertheless, this should do the work with no additional gems :尽管如此,这应该可以在没有额外宝石的情况下完成工作:

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")

No idea about Ruby but the SQL can be simplified to:不知道 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

My answer will assume (since you've provided no ruby/rails-context outside of your raw SQL query) you have a User model, a Micropost model through relation :microposts , and a Relationship model through relation :following .我的回答将假设(因为您在原始 SQL 查询之外没有提供 ruby​​/rails-context)您有一个User模型,一个通过关系:micropostsMicropost模型,以及通过关系:following一个Relationship模型。 User has many Micropost and Relationship instances related. User有许多相关的MicropostRelationship实例。 You could do你可以做

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

or you could move this into a method within Micropost或者您可以将其移动到Micropost的方法中

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

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

This may not be what you're looking for, but in given the above mentioned likely relations you have in your Rails application, it sounds like something similar to this should work.这可能不是您要查找的内容,但考虑到您在 Rails 应用程序中的上述可能关系,听起来应该可以使用类似的方法。

I managed to do it using only where, seems a lot like a find_by_sql to me, and I don't know which one would be better :我设法只使用 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)

Don't know how good this is, but it seem to be working.不知道这有多好,但它似乎有效。

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

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