我有几个班级(精灵、矮人、巨人等),我想通过一个强大的模块为他们添加“权力”,让我向模型添加几个字段/方法(我使用 Mongoid 只是为了例如)使用简单的 DSLhas_superpower(power_name)
module Powerable::Elf
extend ActiveSupport::Concern
include Powerable::Mongoid
has_superpower(:super_hearing)
has_superpower(:night_vision)
end
class Elf
include Powerable::Elf
end
每次我调用类方法has_superpower(power_name)
时,它都应该在power_name
某处注册,这样我以后就可以获取类上所有添加的权力的列表(并反映这些名称以调用其他方法)。
我不知道该怎么做。我查看了类实例变量或类变量,但我不确定如何在这种情况下使用它们
考虑以下样板
module Powerable
module Mongoid
extend ActiveSupport::Concern
def use_power!(power_name, options = {})
send(:"last_#{power_name}_used_at=", Time.now)
...
# Log the power use to the :#{power_name}_uses array
push(#{power_name}_uses, power: power_name, time: Time.now, **options)
end
class_methods do
def has_superpower(power_name)
field :"last_#{power_name}_used_at", type: DateTime
field :"last_#{power_name}_count", type: Integer
field :"#{power_name}_uses", type: Array
end
end
end
现在我想定义一种方法,让我可以使用所有超能力。为此,我需要注册一个人拥有的权力,这样我就可以解析我需要查看的模型字段
# I am adding the following to the above module Powerable::Mongoid
module Powerable
module Mongoid
def power_uses(power_name = nil)
if power_name.blank? # Retrieve all power uses)
self.class.all_powers.flat_map do |power_name|# I do not know how to code all_powers
send(:"#{power_name}_uses")
end
else
send(:"#{power_name}_uses")
end
end
end
end
这个想法
elf = Elf.new
elf.use_power!(:night_vision, moon: :crescent)
elf.use_power!(:super_hearing, distance: 1.kilometer)
elf.power_uses # => [
power: night_vision, time: xxx, moon: :crescent,
power: super_hearing, time: xxx, distance: 1.kilometer
]