Sha256: b6f1945c6453885c642af80fe509145351f19e7ebf23cfc73d33e34ac593e4f0

Contents?: true

Size: 1.52 KB

Versions: 1

Compression:

Stored size: 1.52 KB

Contents

# frozen_string_literal: true

require 'transitions_listener/version'
require 'transitions_listener/listener'

module TransitionsListener
  def self.included(base)
    base.extend(ClassMethods)
    base.class_eval do
      before_update do
        self.class.perform_transition_listeners(self, :before)
      end

      after_update_commit do
        self.class.perform_transition_listeners(self, :after)
      end
    end
  end

  module ClassMethods
    def listen_transitions(attr, &block)
      transition_listeners(TransitionsListener::Listener.new(attr, &block))
    end

    def perform_transition_listeners(model, kind = :before)
      transition_listeners.each do |listener|
        c_transition = current_transition_for(model, listener.attr)
        listener.filter_transitions(kind, c_transition).each do |transition|
          if transition[:block].is_a?(Proc)
            transition[:block].call(model, c_transition.merge(transition))
          else # method name
            model.public_send(transition[:block])
          end
        end
      end
    end

    private

    def transition_listeners(listener = nil)
      @transition_listeners ||= []
      @transition_listeners << listener if listener
      @transition_listeners
    end

    def current_transition_for(model, attr)
      to = model.send(attr)
      from = model.send("#{attr}_was")
      unless model.changed?
        previous = model.send("#{attr}_previous_change")
        from = previous.nil? ? to : previous.first
      end
      { from: from, to: to }
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
transitions_listener-0.2.1 lib/transitions_listener.rb