Sha256: b491114f7ec8db4fb7d7403e7d9eb558aee7ad0620446cadfa394f92bf21a360

Contents?: true

Size: 1.86 KB

Versions: 2

Compression:

Stored size: 1.86 KB

Contents

require 'purgatory/purgatory_module'

class Purgatory < ActiveRecord::Base
  belongs_to :soul, polymorphic: true, autosave: false
  belongs_to :requester, class_name: PurgatoryModule.configuration.user_class_name
  belongs_to :approver, class_name: PurgatoryModule.configuration.user_class_name
  before_create :store_changes
  before_create :destroy_pending_with_same_soul

  validates :soul_type, presence: true

  serialize :requested_changes
  serialize :attr_accessor_fields
  serialize :performable_method

  def self.pending
    where(approved_at: nil)
  end
  
  def self.approved
    where ["approved_at IS NOT NULL"]
  end

  def approved?
    approved_at.present?
  end

  def pending?
    approved_at.nil?
  end

  def soul
    @soul ||= (super || (sti_class || soul_type).constantize.new)
  end

  def sti_class
    requested_changes['type'].try(:last)
  end

  def soul_with_changes
    requested_changes.each{|k,v| soul.send(:write_attribute, k, v[1])} if requested_changes
    attr_accessor_fields.each{|k,v| soul.instance_variable_set(k, v)} if attr_accessor_fields
    soul
  end

  def approve!(approver = nil)
    self.with_lock do
      return false if approved?
      success = soul_with_changes.save
      if performable_method.present? && success
        success = soul.send(performable_method[:method],*performable_method[:args])
      end

      if success
        self.approver = approver
        self.approved_at = Time.now
        self.soul_id = soul.id
        save
        return true
      end
      false
    end
  end

  def self.pending_with_matching_soul(soul)
    pending.where("soul_id IS NOT NULL AND soul_id = ? AND soul_type = ?", soul.id, soul.class.base_class.name)
  end

  private

  def store_changes
    self.requested_changes = soul.changes
  end

  def destroy_pending_with_same_soul
    Purgatory.pending_with_matching_soul(soul).destroy_all
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
purgatory-4.0.0 lib/purgatory/purgatory.rb
purgatory-3.1.2 lib/purgatory/purgatory.rb