我的范围定义如下:
scope :ignore_unavailable, lambda {
where([ "Item.id NOT IN (SELECT id FROM Cars WHERE Cars.status = 'NA'" ])
}
目前使用硬编码表名。如何使用像Arel这样的框架来改进它? 将在这里感谢任何帮助。
我在Rails 3.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的解决方案。
上述代码有两个好处:
答案 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))
}