使用AREL编写“不在”sql查询中
我的范围定义如下:
scope :ignore_unavailable, lambda { where([ "Item.id NOT IN (SELECT id FROM Cars WHERE Cars.status = 'NA'" ]) }
目前它使用硬编码表名。 如何使用像Arel这样的框架来改进它? 将在这里感谢任何帮助。
我在Rails 3.2上
如果你使用的是rails 4,那么就有一种方法
scope :ignore_unavailable, lambda { where.not(id: Car.where(:status => "NA").pluck(:id)) }
对于铁轨3
scope :ignore_unavailable, lambda { where("id not in (?)", Car.where(:status => "NA").pluck(:id)) }
由于任务描述使用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') )
显然,导轨4不具有范围,因此这是导轨3的解决方案。
上面的代码有两个好处:
- 它执行单个查询
- 表列是正确的命名空间(与使用原始sql时不同)