Sha256: 6d7f12ac71ac1ccacecb93faa34665f220db9a92a86dedbb027387c61f8bfc67

Contents?: true

Size: 1.93 KB

Versions: 1

Compression:

Stored size: 1.93 KB

Contents

module Statesman
  module Adapters
    module ActiveRecordQueries
      def self.included(base)
        base.extend(ClassMethods)
      end

      module ClassMethods
        def in_state(*states)
          states = states.map(&:to_s)

          joins(transition1_join)
            .joins(transition2_join)
            .where(state_inclusion_where(states), states)
            .where("transition2.id" => nil)
        end

        def not_in_state(*states)
          states = states.map(&:to_s)

          joins(transition1_join)
            .joins(transition2_join)
            .where("NOT (#{state_inclusion_where(states)})", states)
            .where("transition2.id" => nil)
        end

        private

        def transition_class
          raise NotImplementedError, "A transition_class method should be " +
                                     "defined on the model"
        end

        def initial_state
          raise NotImplementedError, "An initial_state method should be " \
                                     "defined on the model"
        end

        def transition_name
          transition_class.table_name.to_sym
        end

        def model_foreign_key
          reflections[transition_name].foreign_key
        end

        def transition1_join
          "LEFT OUTER JOIN #{transition_name} transition1
             ON transition1.#{model_foreign_key} = #{table_name}.id"
        end

        def transition2_join
          "LEFT OUTER JOIN #{transition_name} transition2
             ON transition2.#{model_foreign_key} = #{table_name}.id
             AND transition2.sort_key > transition1.sort_key"
        end

        def state_inclusion_where(states)
          if initial_state.in?(states)
            'transition1.to_state IN (?) OR ' \
            'transition1.to_state IS NULL'
          else
            'transition1.to_state IN (?) AND ' \
            'transition1.to_state IS NOT NULL'
          end
        end
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
statesman-1.0.0.beta2 lib/statesman/adapters/active_record_queries.rb