如何将模块包含到另一个模块中(将AASM代码和自定义状态重构为模块)

Mik*_*ike 27 ruby refactoring

我正在尝试重构一个超级脂肪模型,该模型有很多与状态和转换相关的ActsAsStateMachine代码,我希望将它重构为模块调用CallStates.

#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
Run Code Online (Sandbox Code Playgroud)

然后在模型中

include CallStates
Run Code Online (Sandbox Code Playgroud)

我的问题涉及如何将模块行为包含到模块中,以便单个模块可以包含在模型中.我已经尝试过class_eval也无济于事.感谢您对此事的任何深刻见解.

Pan*_*kos 43

您不能准确地将一个模块包含在另一个模块中,但是您可以告诉模块在其包含的类中包含其他模块:

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
Run Code Online (Sandbox Code Playgroud)

如果Bmodule实际上是Amodule运行所必需的数据,那么最好只执行此操作,否则会导致混淆,因为它未明确包含在MyClass中.


Jör*_*tag 20

您将模块包含在另一个模块中......当然,将模块包含在另一个模块中!

module Bmodule
  def greet
    puts 'hello world'
  end
end

module Amodule
  include Bmodule
end

class MyClass
  include Amodule
end

MyClass.new.greet # => hello world
Run Code Online (Sandbox Code Playgroud)


Jos*_*ter 15

轨道

对于Rails,你会想要做这样的事情:

module_b.rb

module ModuleB
  extend ActiveSupport::Concern

  included do
    include ModuleA
  end
end
Run Code Online (Sandbox Code Playgroud)

my_model.rb

class MyModel < ActiveRecord::Base

  include ModuleB

end
Run Code Online (Sandbox Code Playgroud)

ModuleA被包括在内ModuleB,然后被包括在MyModel课堂上.


Tom*_*ssi 8

我最喜欢这种语法:

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
Run Code Online (Sandbox Code Playgroud)