1

我有几个班级(精灵、矮人、巨人等),我想通过一个强大的模块为他们添加“权力”,让我向模型添加几个字段/方法(我使用 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
]
4

0 回答 0