重新定义each
中针对规范类ActiveRecord::Base
User
方法
这就是我所知道的
class Rainbow
include Enumerable
def each
yield "red"
yield "orange"
yield "yellow"
yield "green"
yield "blue"
yield "indigo"
yield "violet"
end
end
r = Rainbow.new
r.select { |a| a.start_with?('r')} #=> ["red"]
确定!!
就像我在User Model
class User < ActiveRecord::Base
include Enumerable
def user_ids
User.all.map(&:id) ## instead of this i want to write like User.map(&:id)
end
end
实际上News model
中有大量数据,只需要id
来自所有记录要写User.all.map(&:id)
这样的查询需要花费大量时间。
1:为此,我需要重新定义each method
但是如何?但我需要在每种方法中编写什么代码行。
2:以便所有可枚举方法都可以在该classe对象上调用
还有其他办法。
任何帮助都会非常感激。
答案 0 :(得分:0)
这不是一个好主意。原因是因为ActiveRecord类(以及内部实例方法)既可以作为第一类对象(当您调用Model.foo
时)或通过ActiveRecord::Relation
对象和关联代理进行访问。
很有可能在某些时候会导致一些难以察觉的冲突。
尝试做你想做的事并没有什么好处。实际上,方法
class User < ActiveRecord::Base
include Enumerable
def user_ids
User.all.map(&:id)
end
end
已经可以改写为
def user_ids
User.ids
end
这是
的缩短版def user_ids
User.pluck(:id)
end
请注意,pluck
和ids
都只选择必填字段,因此它们比在加载所有记录和映射字段时更有效(在Ruby级别和数据库级别)。“ / p>
没有提到你的代码可能是错误的。实际上,您正在定义一个应该被称为
的实例方法User.new.user_ids
而您可能希望将其用作
User.user_ids
因此您可以将其定义为
class User < ActiveRecord::Base
def self.user_ids
# User it's implicit, its the current scope
ids
end
end
您可以定义each
class User < ActiveRecord::Base
include Enumerable
def each(&block)
# all returns a lazy-evaluated scope
# that responds to each
# Note that .each will trigger a query.
# In this case, that's effectively equivalent to to_a.each
all.each(&block)
end
end
但它不会给你带来任何好处。此外,这将始终在您调用方法时触发查询,跳过活动记录的非常方便的延迟加载功能。
事实上,ActiveRecord::Relation
也可以作为性能改进来利用延迟加载。
最重要的是,如果您的目标是不键入User.all.map(&:id)
,那么请使用自定义方法,或有效使用Rails API。
User.all.map(&:id)
可以写成
User.pluck(:id)
相当于
User.ids
包含在方法中的变为
class User
def self.user_ids
ids
end
end
User.user_ids