mixin モジュールからステート マシンにコードを挿入できるように、pluginaweek ステート マシン (https://github.com/pluginaweek/state_machine) にモンキー パッチを適用したいと考えています。これを行うためにステートマシンで新しいメソッドを定義する方法を知っている人はいますか? または、おそらく私が達成したいことを行うためのより良い方法がありますか?
仮説として、
class Artifact < ActiveRecord::Base
include Provisionable # << This module makes the magic method 'provision',
# << below, available
state_machine :machine_state, :initial => :s_initial do
# ...
provision(:param1, :param2, :param3) # << The Question: how to define
# << this in the Provisionable mixin
# << module, below
...
end
...
end
module Provisionable
#
# << provision() is supposed to inject the desired code into the state machine:
#
def provision
# << Code sample to be injected begins here:
event :parameterize do
transition :s_unprovisioned => :s_initial
end
before_transition :s_unprovisioned => :s_initial do |artifact, transition|
transition.args.each_pair do |param, value|
# etc...
end
end
# >> Code to be injected ends here.
end
end
ステート マシンを購入する場合は、これを強くお勧めします。
ありがとう!
[後で追加:] 私は解決策を考え出しました。これが他の人に役立つことを願っています。モジュールを混在させる代わりに、state_machine にモンキー パッチを適用して、コードを挿入するインスタンス メソッドを追加しました。
StateMachine::Machine.class_eval do
def inject_provisioning()
event :start do
transition :s_initial => :s_provisioning
end
after_transition :s_initial => :s_provisioning do |goal, transition|
# Do useful stuff here
true
end
event :provision do
transition :s_provisioning => :s_completed
end
before_transition :s_provisioning => :s_completed do |goal, transition|
artifact_type = transition.args[0]
params = transition.args[1]
# Useful stuff here
true
end
after_transition :s_provisioning => :s_completed do |goal, transition|
artifact_type = transition.args[0]
params = transition.args[1]
# Useful stuff here
end
end
def inject_expiration()
event :chron do
expired_callback = lambda \
do |goal|
return false if goal.expires_at == :never
goal.expires_at.to_i < DateTime.now.to_i
end
active_callback = lambda \
do |goal|
return true if goal.expires_at == :never
goal.expires_at.to_i >= DateTime.now.to_i
end
transition all - :s_expired => :s_expired, :if => expired_callback
end
before_transition all - :s_expired => :s_expired do |goal, transition|
goal.undo
end
end
これで、クラスで state_machine 定義を開いているときに、単純なマクロのような呼び出しを行ってコードを挿入できます。
state_machine :machine_state, :initial => :s_initial do
inject_provisioning
inject_expiration
end
他の誰かがこれが役に立つことを願っています。