【问题标题】:find all that are nil in the association找出关联中所有的 nil
【发布时间】:2011-02-09 16:43:03
【问题描述】:

所以我有一个帖子和一个用户。
帖子有_许多用户和一个用户属于_一个帖子。
我需要一个查找来查找所有没有任何用户的帖子,如下所示:

Post.first.users
 => [] 

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3


    【解决方案1】:
    Post.where("id not in (select post_id from users)")
    

    【讨论】:

    • 如果子查询包含 nil,则不会返回任何内容,您可能希望使用 NOT EXISTS 代替,就像我在特定情况下需要的那样。 Further reading.
    【解决方案2】:

    今天才学这个:

    Post.eager_load(:users).merge(User.where(id: nil))
    

    至少适用于 Rails 4+。

    更新:

    在 Rails 5+ 中,您可以改用 left_joins

    Post.left_joins(:users).merge(User.where(id: nil))
    

    【讨论】:

      【解决方案3】:

      类似的东西:

      p = Post.arel_table
      u = User.arel_table
      
      posts = Post.find_by_sql(p.join(u).on(p[:user_id].eq(u[:p_id])).where(u[:id].eq(nil)).to_sql) 
      

      【讨论】:

        【解决方案4】:

        我知道这被标记为 Rails 3,但如果您使用的是 Rails 4,我一直在这样做。

        Post.where.not(user_id: User.pluck(:id))
        

        【讨论】:

          【解决方案5】:

          如果您需要快速的东西,请使用如下 SQL 语句:

          SELECT * 
          FROM posts p 
          LEFT OUTER JOIN users u ON p.id = u.post_id 
          WHERE u.id IS null
          

          【讨论】:

            【解决方案6】:

            我猜如果数据库表有很多行,带有 in 的 sql 可能会导致性能问题。小心点

            【讨论】:

            • 对。从最易读的代码开始,用测试保护它,然后你就可以开始优化性能了。如果没有测试,您可能会意外“优化掉”一些记录。并始终衡量实际性能:优化版本并不总是最快的。
            【解决方案7】:

            如果用户返回一个数组,Post.first.users.empty? 应该足够了。

            如果您想检查每个帖子,您可以这样做

            Post.each do |p|
              if p.users.empty?
                do whatever
              end
            end
            

            【讨论】:

            • 我需要找到所有的帖子...不仅仅是第一个
            • 所以我需要 Post.all(:include => :users, :conditions => "users = ?", nil)
            • Post.each do |p| if p.users == nil do whatever end end
            猜你喜欢
            • 1970-01-01
            • 2021-04-14
            • 1970-01-01
            • 2011-02-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-18
            相关资源
            最近更新 更多