写作"不在"使用AREL的SQL查询

时间:2014-09-05 19:09:59

标签: ruby-on-rails arel

我的范围定义如下:

scope :ignore_unavailable, lambda { 
  where([ "Item.id NOT IN (SELECT id FROM Cars WHERE Cars.status = 'NA'" ])
}

目前使用硬编码表名。如何使用像Arel这样的框架来改进它? 将在这里感谢任何帮助。

我在Rails 3.2上

2 个答案:

答案 0 :(得分:9)

由于任务描述使用AREL请求答案,我提出以下内容:

class Car
  scope :available, -> { where(arel_table[:status].not_in(['NA'])) }
end

class Item
  scope :available, -> { where(:id => Car.available) }
end

sql应该类似于以下内容:

SELECT [items].*
FROM [items]
WHERE [item].[id] IN (
    SELECT [cars].[id]
    FROM [cars]
    WHERE [car].[status] NOT IN ('NA')
  )

显然,rails 4具有not范围,因此这是rails 3的解决方案。

上述代码有两个好处:

  • 执行单个查询
  • 表列正确命名空间(与使用原始sql时不同)

答案 1 :(得分:4)

如果你使用的是rails 4,那么一种方式就是

scope :ignore_unavailable, lambda {
  where.not(id: Car.where(:status => "NA").pluck(:id))
}

对于rails 3

scope :ignore_unavailable, lambda {
  where("id not in (?)", Car.where(:status => "NA").pluck(:id))
}