我正在尝试重构一个超级脂肪模型,它有很多与状态和转换相关的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
然后在模型中
include CallStates
我的问题涉及如何将模块行为包含到模块中,以便单个模块可以包含在模型中。我已经尝试过class_eval也无济于事。感谢您对此事的任何深刻见解。
答案 0 :(得分:41)
您不能准确地将一个模块包含在另一个模块中,但是您可以告诉模块在其所包含的类中包含其他模块:
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中。
答案 1 :(得分:19)
您将模块包含到另一个模块中......当然,将模块包含在另一个模块中!
module Bmodule
def greet
puts 'hello world'
end
end
module Amodule
include Bmodule
end
class MyClass
include Amodule
end
MyClass.new.greet # => hello world
答案 2 :(得分:14)
对于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
ModuleA
包含在ModuleB
中,然后包含在MyModel
类中。
答案 3 :(得分: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