I'm trying to refactor a superfat model which has quite a few lines of ActsAsStateMachine code related to the states and transitions, and I was hoping to refactor this to a module call 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
And then in the model
include CallStates
My question concerns how to include Module behavior into a Module such that a single Module can be included into the model. I've tried class_eval do as well to no avail. Thanks for any insightful thoughts you have on the matter.
A Ruby class can have only one superclass, but it can include any number of modules. These modules are called mixins. If you write a chunk of code that can add functionality to classes in general, it should go into a mixin module instead of a class.
You can't include one module in another exactly, but you can tell a module to include other modules in the class into which it's included:
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
It's best to only do this if Bmodule is actually data that is necessary for Amodule to function, otherwise it can lead to confusion because it's not explicitly included in MyClass.
You include a module into another module by ... including a module into another module, of course!
module Bmodule
def greet
puts 'hello world'
end
end
module Amodule
include Bmodule
end
class MyClass
include Amodule
end
MyClass.new.greet # => hello world
For Rails, you'll want to do something like this:
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
is being included in ModuleB
, which is then included in MyModel
class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With