J'essaie de refactoriser un modèle superfat qui a pas mal de lignes de code ActsAsStateMachine liées aux états et aux transitions, et j'espérais refactoriser cela en un module appelé 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
Et puis dans le modèle
include CallStates
Ma question concerne la façon d'inclure le comportement du module dans un module de telle sorte qu'un seul module puisse être inclus dans le modèle. J'ai essayé class_eval faire aussi bien en vain. Merci pour toutes vos idées perspicaces à ce sujet.
Vous ne pouvez pas inclure un module dans un autre exactement, mais vous pouvez dire à un module d'inclure d'autres modules dans la classe dans laquelle il est inclus:
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
Il est préférable de ne le faire que si Bmodule est en fait des données nécessaires au fonctionnement d'Amodule, sinon cela peut entraîner de la confusion car il n'est pas explicitement inclus dans MyClass.
Vous incluez un module dans un autre module en ... incluant un module dans un autre module, bien sûr!
module Bmodule
def greet
puts 'hello world'
end
end
module Amodule
include Bmodule
end
class MyClass
include Amodule
end
MyClass.new.greet # => hello world
Pour Rails, vous voudrez faire quelque chose comme ceci:
module_b.rb
module ModuleB
extend ActiveSupport::Concern
included do
include ModuleA
end
end
mon_modèle.rb
class MyModel < ActiveRecord::Base
include ModuleB
end
ModuleA
est inclus dans ModuleB
, qui est ensuite inclus dans MyModel
classe.
J'aime mieux cette syntaxe:
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