【问题标题】:Rails way to write SQL EXISTS for Active Record?Rails 为 Active Record 编写 SQL EXISTS 的方式?
【发布时间】:2018-02-28 14:04:47
【问题描述】:

我有以下设置:

class Company
  has_many :users
end

class User
  belongs_to :company
end

我需要获取所有没有特定名称用户的公司,让它成为“大卫”。

反之亦然,查找所有拥有名为 David 的用户的公司:

Company.joins(:users).where(users: { name: 'David' }).distinct

但我不知道如何在一个 SQL 请求中完成原始任务。 我试过这个:

Company.joins(:users).where.not(users: { name: 'David' }).distinct

但它并没有像我想象的那样工作。

所以我做了一个原始的 SQL 解决方案,查询是:

"SELECT companies 
  FROM companies 
  WHERE NOT EXISTS 
    (SELECT users 
      FROM users 
      WHERE users.company_id = companies.id 
      AND users.name = 'David')"

所以我想知道是否有办法以 rails 方式执行此任务,使用连接和 where 方法,或者可能还有 EXISTS 的方法。

【问题讨论】:

    标签: sql ruby-on-rails ruby activerecord exists


    【解决方案1】:

    只需将连接替换为包含

    Company.includes(:users).where.not(users: { name: 'David' })
    

    【讨论】:

    • 您能否评论一下includesjoins 之间的区别以及为什么提议的更改应该有效?
    • 基本上includes 使用急切加载,而joins 使用延迟加载。您可以查看更多here
    • @Aqabawe 您的查询问题与连接问题相同。例如,我们只有一家公司有两个用户——大卫和歌利亚。您的查询将返回该公司(应返回 nil),因为它确实搜索 公司,这些公司至少有一个用户的名称与 David 不同。所以问题仍然没有解决。
    【解决方案2】:

    嗯,最终 ActiveRecord 没有 SQL 的全部功能,所以我最终使用了原始 SQL。

    仍然有一个 gem 将 EXISTS 添加到 ActiveRecord: https://github.com/EugZol/where_exists

    如果您想不惜一切代价避免使用原始 SQL,您可以使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多