根据Rails文档中的scope
,范围如下:
class Shirt < ActiveRecord::Base
scope :red, -> { where(color: 'red') }
end
确实是:
class Shirt < ActiveRecord::Base
def self.red
where(color: 'red')
end
end
他们还说,该关系应充当Array
,因此请执行以下操作
Shirt.red.each(&block)
应该可以工作...而且确实可以。
使用上面我们知道的一切,为什么以下操作不起作用?
class Shirt < ActiveRecord::Base
def self.short_sleeved
reject{|object| object.short_sleeved == false}
end
end
Shirt.red.short_sleeved
结果是 undefined method 'reject' for #<Class:0xba552d4>
您无法short_sleeved
按照尝试的方式定义方法,因为ActiveRecord类不是ActiveRecord关系。
您short_sleeved
在上定义Shirt
。Shirt
是一个ActiveRecord模型类。它本身不是ActiveRecord关系。它具有的方法包括all
和where
和其他许多返回ActiveRecord关系的方法。
Shirt.class
=> Class
Shirt.respond_to? :each
=> false
Shirt.respond_to? :reject
=> false
像内置查询方法一样,作用域返回ActiveRecord关系。ActiveRecord关系具有动态生成的类。它不是一个Enumerable
但对Enumerable
方法的响应:
red_shirts = Shirt.red
red_shirts.class
=> Shirt::ActiveRecord_Relation
red_shirts.respond_to? :each
=> true
red_shirts.respond_to? :reject
=> true
因此,您可以通过以下方式编写方法:
def self.short_sleeved
all.reject { |object| object.short_sleeved == false }
end
但是,这会Shirt
从数据库中加载所有s,然后将其过滤到内存中,对于大量Shirt
s而言,效率where
不如MZaragosa建议的那样在数据库中进行过滤。你可以这样
def self.short_sleeved
where short_sleeved: true
end
或者
scope :short_sleeved, -> { where short_sleeved: true }
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句