Ruby on Rails的空范围
以下问题:
我需要像空的范围。 这意味着此范围是emtpy,但响应范围通常响应的所有方法。 我目前正在使用一些肮脏的黑客。 我只是提供“1 = 0”作为条件。 我觉得这很难看,因为它击中了数据库。 简单地返回一个空数组将不起作用,因为结果必须响应作用域方法。
有没有更好的现有解决方案或我需要自己编码?
也许一些示例代码可以帮助解释我需要的东西:
class User {:admin => true } named_scope :none_dirty, :conditions => "1=0" # this scope is always empty def none_broken [] end def self.sum_score # okay, a bit simple, but a method like this should work! total = 0 self.all.each do |user| total += user.score end return total end end User.admin.sum_score # the score i want to know User.none_drity.sum_score # works, but hits the db User.none_broken.sum_score # ...error, since it doesn't respond to sum_score
Rails 4引入了none
范围。
它适用于您有一个返回关系的方法的情况,但是有一种情况是您不希望查询数据库。
如果您希望范围返回未更改的范围,请使用all
:
不再调用Model.all
立即执行查询并返回记录数组。 在Rails 4中,对Model.all
调用相当于现在已弃用的Model.scoped
。 这意味着可以将更多关系链接到Model.all
,并且结果将被懒惰地评估。
User.where('false')
返回一个具有零元素的ActiveRecord :: Relation,这是一个可链的范围,在您实际尝试访问其中一个元素之前,它不会命中数据库。 这类似于PhilT的解决方案(’1 = 0’),但更优雅一点。
对不起User.scoped
不是你想要的。 如此评论,这将返回一切。 应该更加关注这个问题。
我已经看过之前建议的where('1 = 0')
,Rails也应该缓存它。
此外, where('1 = 0')
执行.each
, .each
或其中一种计算方法之前, where('1 = 0')
不会命中数据库。
我需要User.scoped({})
User.where(id: nil)
怎么样?
或者User.where(_id: nil)
为mongoid。
你正在寻找的东西是不存在的。 你可以通过monky修补find
方法来实现这样的东西。 然而,这将是一个矫枉过正,所以我建议保持这个,除非它的性能至关重要。
查看示例代码表明您可能不了解SQL中的聚合查询,这些查询在Rails中作为计算方法公开:
User.sum(:score)
将为您提供所有用户分数的总和
有关更多信息,请查看Rails指南:
http://guides.rubyonrails.org/active_record_querying.html#sum