define_method の「module」ブロック内でメソッド呼び出しを使用できないのはなぜですか?
概要
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
例えば:
次のようなモデルメソッドを使用すると、同じエラーが発生します。
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 を使用することは可能ですか?そうでない場合、なぜそうなるのでしょうか?
解決策
提供された情報から、モジュール 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 を使用する場合は、たとえば、付属のメソッドを使用する必要があります
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"