module AffairsOfState::ActiveRecordExtension

Public Instance Methods

affairs_of_state(*statuses, column: :status, allow_blank: false, scopes: true, if: nil, prefix: nil) click to toggle source
# File lib/affairs_of_state/active_record_extension.rb, line 7
def affairs_of_state(*statuses, column: :status, allow_blank: false, scopes: true, if: nil, prefix: nil)
  # config object that defines behaviour
  config = AffairsOfState::Config.new(
    statuses: statuses,
    prefix: prefix,
    column: column,
    allow_blank: !!allow_blank,
    scopes: scopes,
    if: binding.local_variable_get(:if)
  )

  # check for conflicts with existing calls
  raise ArgumentError, "Affairs of State: #{ self } has already been called on `#{ config.column }`" if affairs_of_state_configs[config.column]
  statuses_and_methods = affairs_of_state_configs.values.map(&:methods_for_statuses).map { |m| m.map{ |(k, v)| [k, v] } }.flatten
  overlapping_statuses = statuses_and_methods & config.methods_for_statuses.map{ |k, v| [k, v] }.flatten
  raise ArgumentError, "Affairs of State: #{ self } already has a status #{ overlapping_statuses }" if overlapping_statuses.any?

  # status methods
  config.methods_for_statuses.each do |status, method_name|
    define_method("#{ method_name }?") do
      self.send(config.column) == status
    end

    define_method("#{ method_name }!") do
      self.send("#{ config.column }=", status)
      self.save
    end
  end

  # scopes
  if config.scopes
    config.methods_for_statuses.each do |status, method_name|
      self.scope(method_name.to_sym, -> { where(config.column => status) })
    end
  end

  # column validation
  validates(config.column, inclusion: { in: config.statuses, allow_blank: config.allow_blank }, if: config.if)

  # cache the config on the object
  affairs_of_state_configs[config.column] = config

  include InstanceMethods
  extend SingletonMethods

  true
end
affairs_of_state_configs() click to toggle source
# File lib/affairs_of_state/active_record_extension.rb, line 55
def affairs_of_state_configs
  @affairs_of_state_configs ||= {}
end