Sha256: e3a362bc3a3100c9f8f5bf8a61a350b61de4e617a4cedc7eca5a434234bde2df

Contents?: true

Size: 1.69 KB

Versions: 1

Compression:

Stored size: 1.69 KB

Contents

require "active_record"

module SimpleStateMachine
  module ActiveRecord
    extend ActiveSupport::Concern
    
    included do |base|
      base.extend ClassMethods
    end

    module ClassMethods
      def state_machine(column, states)
        create_empty_state_machine unless inheritable_attributes.key? :states
        inheritable_attributes[:states][column.to_sym] = states
        validates_inclusion_of column, :in => states
        # should also override getter/setter to convert to strings
        self.class_eval <<-eos
          def #{column.to_s}=(value)
            self[:#{column.to_s}] = value.to_s
          end
          def #{column.to_s}
            self[:#{column.to_s}].to_sym
          end
          def #{column.to_s}_revert
            self[:#{column.to_s}] = self.new_record? ? states[:#{column.to_s}].first.to_s : self.#{column.to_s}_was
          end
        eos

        # define a method {state_column}_{state}? for each state
        states.each do |state|
          self.class_eval <<-eos
            def #{column.to_s}_#{state.to_s}?
              self[:#{column.to_s}] === "#{state.to_s}"
            end
          eos
        end

      end

    private

      def create_empty_state_machine
        write_inheritable_attribute :states, {} # add a class variable
        class_inheritable_reader    :states     # make it read-only
    
        after_initialize :set_initial_states
        self.class_eval do
          def set_initial_states
            states.each {|column, states|
              self[column] = states.first.to_s
            } if new_record?
          end
        end
      end
    end
  end
end

ActiveRecord::Base.class_eval do
  include SimpleStateMachine::ActiveRecord
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
openhood-simple_state_machine-2.0.0 lib/simple_state_machine/active_record.rb