如果我有一个带lambda的作用域并且它接受一个参数,则取决于参数的值,我可能知道不会有任何匹配项,但是我仍然想返回一个关系,而不是一个空数组:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
我真正想要的是“无”方法,与“全部”相反,该方法返回仍然可以链接的关系,但导致查询短路。
如果我有一个带lambda的作用域并且它接受一个参数,则取决于参数的值,我可能知道不会有任何匹配项,但是我仍然想返回一个关系,而不是一个空数组:
scope :for_users, lambda { |users| users.any? ? where("user_id IN (?)", users.map(&:id).join(',')) : [] }
我真正想要的是“无”方法,与“全部”相反,该方法返回仍然可以链接的关系,但导致查询短路。
Answers:
Rails 4现在提供了一种“正确”的机制:
>> Model.none
=> #<ActiveRecord::Relation []>
Model.scoped
您在轨道3中的需求。–
Model.none
它不起作用。您需要使用您的真实模型名称之一,例如,User.none
或者您拥有什么。
一个更可移植的解决方案,不需要“ id”列,并且不假设不会有id为0的行:
scope :none, where("1 = 0")
我仍在寻找一种更“正确”的方法。
scope :none, -> { where("false") }
您可以添加一个名为“ none”的范围:
scope :none, where(:id => nil).where("id IS NOT ?", nil)
这将为您提供一个空的ActiveRecord :: Relation
您也可以将其添加到初始化程序的ActiveRecord :: Base中(如果需要):
class ActiveRecord::Base
def self.none
where(arel_table[:id].eq(nil).and(arel_table[:id].not_eq(nil)))
end
end
有很多方法可以得到这样的东西,但肯定不是保存在代码库中的最佳方法。我在重构时使用了作用域:none,发现需要在短时间内保证一个空的ActiveRecord :: Relation。
where('1=2')
可能会更简洁一点
Model.none
是您的操作方式。
我认为与其他选项相比,我更喜欢这种外观:
scope :none, limit(0)
导致这样的事情:
scope :users, lambda { |ids| ids.present? ? where("user_id IN (?)", ids) : limit(0) }
where(false)
不做这项工作-它使范围保持不变。
limit(0)
如果您在链中调用.first
或.last
稍后调用,它将被覆盖,因为Rails将追加LIMIT 1
到该查询。
none
下面提到的关系。
使用范围:
范围:for_users,lambda {| users | 用户吗??where(“ user_id IN(?)”,users.map(&:id).join(',')):作用域}
但是,您还可以使用以下方法简化代码:
范围:for_users,lambda {| users | where(:user_id => users.map(&:id))如果是users.any?}
如果您想要一个空结果,请使用此命令(删除if条件):
范围:for_users,lambda {| users | where(:user_id => users.map(&:id))}
可能是这样的:
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
如我错了请纠正我。