ruby 为什么我不能在define_method的“module”块中使用方法调用?

sd2nnvve  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(65)

我有一个模型类attr_reader -type_slugs(返回一个字符串数组),我想用它来生成几个方法。
举例来说:

module Orders
  module Extensions
    module Order
      module TypeCheckable
        extend ::ActiveSupport::Concern

        ::Orders::Config.type_slugs.each do |type|
          define_method("#{type}_order_type?") { order_type == type }
        end
      end
    end
  end
end

但它给了我NoMethodError: undefined methodtype_slugs' for Orders::Config:Module`
如果我使用任何模型方法,也会发生同样的错误,比如:

some_method_defined_in_model.each do |type|
  define_method("#{type}_order_type?") { order_type == type }
end

但是如果我用一个单词数组

%w(message product another).each do |type|
  define_method("#{type}_order_type?") { order_type == type }
end

在这种情况下,是否可以使用Orders::Config.type_slugs?若否,原因为何?

xzlaal3s

xzlaal3s1#

根据您提供的信息,模块Orders::Config没有type_slugs方法
如果你想让你的代码工作,你需要定义它,像这样:

module Orders
  module Config
    def self.type_slugs
      %w[message product another]
    end
  end
end

或者,如果该列表不动态更改:

module Orders
  module Config
    TYPE_SLUGS = %w[message product another].freeze
  end
end

在这种情况下,将::Orders::Config.type_slugs更改为::Orders::Config::TYPE_SLUGS
当使用Rails concerns时,应该为示例方法使用included

module Orders
  module Extensions
    module Order
      module TypeCheckable
        extend ::ActiveSupport::Concern

        included do
          ::Orders::Config::TYPE_SLUGS.each do |type|
            define_method("#{type}_order_type?") { order_type == type }
          end
        end
      end
    end
  end
end

之后,您可以在模型中使用它

class SuperOrder < ApplicationRecord
  include Orders::Extensions::Order::TypeCheckable
end

class BestOrder < ApplicationRecord
  include Orders::Extensions::Order::TypeCheckable
end

并像这样调用方法

SuperOrder.new.product_order_type? # compare super order type with "product"
BestOrder.new.message_order_type? # compare best order type with "message"

相关问题