我在我的Rails应用程序中使用postgres架构,因此没有明确的方法可以跨所有公司进行查询(对于我们自己的分析)。我想实现迭代所有公司的每种方法,并适当地切换postgres模式。
我希望能够致电:
Company.each do |company|
# do something in the context of each company
end
但我也希望获得一些其他可枚举方法,例如collect
,这个例子可以让所有公司的所有经理都获得:
Company.collect do |company|
Users.managers
end
目前我有这个效果很好
class Company < ActiveRecord::Base
# ...
def self.each(&block)
Company.all.each do |company|
if Schemas.include? company.subdomain
# this changes to that company's schema so all queries are scoped
Apartment::Database.switch company.subdomain
yield company if block_given?
end
end
end
但是如何在类级而不是实例级别获得Enumerable mixin。
即,当include Enumerable
在类中时,可以像
company = Company.new
# which might iterate over the contents (users?) in a company
company.collect {|u| u}
但我想打电话
# iterate over all companies and collect the managers
Company.collect {|c| User.managers}
并使用
Company.each
我觉得答案很明显,但我的元编程foo今天早上很弱。
答案 0 :(得分:4)
您可以在include
内使用class << self
:
class Foo
class << self
include Enumerable
end
def self.each
yield 1
yield 2
yield 3
end
end
Foo.map { |x| x * 2 } # => [2, 4, 6]
此模式用于Ruby的Prime
class。编写include
以包含模块对我来说看起来更干净,但您也可以使用extend
(请参阅Uri Agassi's answer)。
如果所包含的模块依赖于included
回调(Enumerable
没有),则会有所不同:
module M
def self.included(other)
puts "included in #{other}"
end
end
class Foo
class << self
include M
end
end
#=> "included in #<Class:Foo>"
class Bar
extend M
end
#=> nothing
作为noted by Зелёный,您可以在块内定义each
:(并且不使用self
)
class Foo
class << self
include Enumerable
def each
# ...
end
end
end
答案 1 :(得分:3)
要在课堂上“包含Enumerable”,请使用extend
class Company
extend Enumerable
def self.each
yield 'a'
yield 'b'
yield 'c'
end
end
Company.inject(&:+)
# => "abc"