【问题标题】:Convert some SQL query to active record将一些 SQL 查询转换为活动记录
【发布时间】:2012-08-06 22:52:15
【问题描述】:

所以,我有这个“高级”查询(真的不多),我想把它翻译成 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 以 desc 创建顺序跟随用户,但我真的不知道如何使用 Active Record 的语法轻松翻译。

有什么想法吗?

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

我有 3 个模型:MicropostsUsersRelationships

  • Relationships 是处理所有用户关系(关注者/关注者)的连接表。
  • 用户通过关系拥有许多followed_users/followers。
  • 用户有多个微环,微环有一个用户。

谢谢。

【问题讨论】:

  • 感谢您的可读性修复,ypercube :)

标签: sql ruby-on-rails ruby activerecord


【解决方案1】:

不了解 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

【讨论】:

    【解决方案2】:

    我的回答将假设 (因为您在原始 SQL 查询之外没有提供任何 ruby​​/rails-context)您有一个 User 模型,一个 Micropost 模型通过关系 @987654324 @ 和 Relationship 模型通过关系 :followingUser 有许多相关的 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 应用程序中可能存在的关系,听起来与此类似的东西应该可以工作。

    【讨论】:

    • 哦,对不起,我完全忘记了指定我的模型和关联。但你是对的,我会纠正它。
    • 但这不是我要找的,因为这将给我用户的微博,然后按顺序给我所有关注的用户微博。我需要按日期排序的所有用户和用户关注的用户微博。以某种方式使用 twitter、facebook 等。
    • AREL 是否将 + 转换为 UNION?
    • 不,那是 joining to arrays
    【解决方案3】:

    您的查询非常具体,因此最好的办法是使用 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")
    

    【讨论】:

      【解决方案4】:

      我设法只使用 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)
      

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

      【讨论】:

        猜你喜欢
        • 2015-07-17
        • 1970-01-01
        • 1970-01-01
        • 2011-10-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-11
        相关资源
        最近更新 更多