如果我有一个带lambda的作用域,它接受一个参数,这取决于参数的值,我可能知道不会有任何匹配,但我仍然想返回一个关系,而不是一个空数组:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
我真正想要的是一个“none”方法,与“all”相反,它返回一个仍然可以被链接的关系,但会导致查询短路。
如果我有一个带lambda的作用域,它接受一个参数,这取决于参数的值,我可能知道不会有任何匹配,但我仍然想返回一个关系,而不是一个空数组:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
我真正想要的是一个“none”方法,与“all”相反,它返回一个仍然可以被链接的关系,但会导致查询短路。
当前回答
也有变体,但所有这些都是向db发出请求
where('false')
where('null')
其他回答
Rails 4
在Rails 4中,可链接的ActiveRecord::NullRelation将从Post.none等调用中返回。
它和链式方法都不会生成对数据库的查询。
根据评论:
返回的ActiveRecord::NullRelation继承自 关系并实现空对象模式。它是一个对象 定义了空行为,并始终返回记录的空数组 不需要查询数据库。
参见源代码。
使用范围:
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)) }
比起其他选择,我更喜欢这种方式:
scope :none, limit(0)
导致这样的结果:
scope :users, lambda { |ids| ids.present? ? where("user_id IN (?)", ids) : limit(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
如果我说错了,请指正。
也有变体,但所有这些都是向db发出请求
where('false')
where('null')