I am trying to factor out some duplicated logic into a concern. Part of the duplicated logic is a state_machine.
Simplified, the Database, Site, SftpUser and more contain, amongst others, this:
class Database < ActiveRecord::Base
# ...
state_machine :deploy_state, initial: :halted do
state :pending
end
end
I'm attempting to refactor this into a concern:
module Deployable
extend ActiveSupport::Concern
included do
state_machine :deploy_state, initial: :halted do
state :pending
end
end
end
# Tested with:
class DeployableDouble < ActiveRecord::Base
extend Deployable
end
describe DeployableDouble do
let(:subject) { DeployableDouble.new }
it "should have default state halted" do
subject.deploy_state.must_equal "halted"
end
end
However, this is not the correct way to implement a state_machnine in a concern, because this results in: NoMethodError: undefined method 'deploy_state' for <DeployableDouble:0xb9831f8>. Which indicates that the Double did not get a statemachine assigned at all.
Is the included do actually the right callback to implement this? Is it maybe an issue with state_machine, it needing a subclass of ActiveRecord::Base or so? Something I'm not getting? I am pretty new to the concept of Concerns.
Okay. I am feeling really stupid. One should not
extenda class with a module, butincludethat module. Obviously.One of these things that you oversee once written. Also, extending the
ActiveRecord::Baseis not needed, since state_machine is just plain old Ruby and works on a generic Ruby Object.