gpt4 book ai didi

ruby-on-rails - 为什么这种类似作用域的查询方式不能使用reject呢?

转载 作者:太空宇宙 更新时间:2023-11-03 16:19:17 24 4
gpt4 key购买 nike

根据 Rails documentation for 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 关系。

您在 Shirt 上定义了 short_sleevedShirt 是一个 ActiveRecord 模型类。它本身不是 ActiveRecord 关系。它的方法包括 allwhere 以及许多其他返回 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,然后在内存中过滤它们,对于大量的 Shirt,这不如执行按照 MZaragosa 的建议,使用 where 在数据库中进行过滤。你可以这样做

def self.short_sleeved
where short_sleeved: true
end

scope :short_sleeved, -> { where short_sleeved: true }

关于ruby-on-rails - 为什么这种类似作用域的查询方式不能使用reject呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37218385/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com