如果我有一个带lambda的作用域,它接受一个参数,这取决于参数的值,我可能知道不会有任何匹配,但我仍然想返回一个关系,而不是一个空数组:

scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }

我真正想要的是一个“none”方法,与“all”相反,它返回一个仍然可以被链接的关系,但会导致查询短路。


当前回答

这是可能的,所以

scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : User.none }

http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/none

如果我说错了,请指正。

其他回答

使用范围:

scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : scoped }

但是,你也可以简化你的代码:

scope :for_users, lambda { |users| where(:user_id => users.map(&:id)) if users.any? }

如果你想要一个空的结果,使用这个(去掉If条件):

scope :for_users, lambda { |users| where(:user_id => users.map(&:id)) }

一个更可移植的解决方案,不需要“id”列,也不假设不会有id为0的行:

scope :none, where("1 = 0")

我还在寻找一种更“正确”的方式。

比起其他选择,我更喜欢这种方式:

scope :none, limit(0)

导致这样的结果:

scope :users, lambda { |ids| ids.present? ? where("user_id IN (?)", ids) : limit(0) }
scope :none, limit(0)

是一个危险的解决方案,因为您的瞄准镜可能会被链接。

User.none.first

将返回第一个用户。使用起来更安全

scope :none, where('1 = 0')

这是可能的,所以

scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : User.none }

http://apidock.com/rails/v4.0.2/ActiveRecord/QueryMethods/none

如果我说错了,请指正。