web-dev-qa-db-ja.com

モジュールを別のモジュールに含めるにはどうすればよいですか(AASMコードとカスタム状態をモジュールにリファクタリングする)

私は、状態と遷移に関連するActsAsStateMachineコードのかなりの数行を持つスーパーファットモデルをリファクタリングしようとしています。これをCallCallsモジュール呼び出しにリファクタリングしたいと思っていました。

#in lib/CallStates.rb
module CallStates
    module ClassMethods
        aasm_column :status
        aasm_state :state1
        aasm_state :state2
        aasm_state :state3
    end

    def self.included(base)
        base.send(:include, AASM)
        base.extend(ClassMethods)
    end
end

そしてモデルで

include CallStates

私の質問は、単一のモジュールをモデルに含めることができるように、モジュールの動作をモジュールに含める方法に関するものです。 class_evalも試しましたが、うまくいきませんでした。あなたが問題について洞察に満ちた考えをありがとう。

30
Mike

あるモジュールを別のモジュールに正確に含めることはできませんが、モジュールに、それが含まれているクラスに他のモジュールを含めるように指示できます。

module Bmodule
  def greet
    puts 'hello world'
  end
end

module Amodule
  def self.included klass
    klass.class_eval do
      include Bmodule
    end
  end
end

class MyClass
  include Amodule
end

MyClass.new.greet # => hello world

これは、Bmoduleが実際にAmoduleが機能するために必要なデータである場合にのみ行うことをお勧めします。そうでない場合、MyClassに明示的に含まれていないため、混乱を招く可能性があります。

42
Pan Thomakos

もちろん、モジュールを別のモジュールに組み込みます。モジュールを別のモジュールに組み込みます。

module Bmodule
  def greet
    puts 'hello world'
  end
end

module Amodule
  include Bmodule
end

class MyClass
  include Amodule
end

MyClass.new.greet # => hello world
19
Jörg W Mittag

Rails

Railsの場合、次のようなことを行います。

module_b.rb

module ModuleB
  extend ActiveSupport::Concern

  included do
    include ModuleA
  end
end

my_model.rb

class MyModel < ActiveRecord::Base

  include ModuleB

end

ModuleAModuleBに含まれ、次にMyModelクラスに含まれます。

15
Joshua Pinter

私はこの構文が一番好きです:

module Bmodule
  def greet
    puts 'hello world'
  end
end

module Amodule
  def self.included(receiver)
    receiver.send :include, Bmodule
  end
end

class MyClass
  include Amodule
end

MyClass.new.greet # => hello world
8
Tom Rossi