Sha256: 09bd67db152890e47ef47f0ed22cd67a7457491230d068d06783a3faa90ad8b3

Contents?: true

Size: 2 KB

Versions: 1

Compression:

Stored size: 2 KB

Contents

require 'active_support/core_ext/class/attribute'

module RailsStuff
  # Adds `types_list` method which tracks all descendants.
  # Also allows to remove any of descendants from this list.
  # Useful for STI models to track all available types.
  #
  # Railtie adds `to_prepare` callback, which will automatically load types.
  module TypesTracker
    class << self
      def extended(base)
        base.class_attribute :types_list, instance_accessor: false
        base.types_list = types_list_class.new
        base.instance_variable_set(:@_types_tracker_base, base)
      end

      # Class for `types_list`. Default to `Array`. You can override it
      # for all models, or assign new value to specific model
      # via `lypes_list=` right after extending.
      attr_accessor :types_list_class
    end

    self.types_list_class = Array

    # Add `self` to `types_list`. Defines scope for ActiveRecord models.
    def register_type(*args)
      if types_list.respond_to?(:add)
        types_list.add self, *args
      else
        types_list << self
      end
      if types_tracker_base.respond_to?(:scope) && # rubocop:disable GuardClause
          !types_tracker_base.respond_to?(model_name.element)
        type_name = name
        types_tracker_base.scope model_name.element, -> { where(type: type_name) }
      end
    end

    # Remove `self` from `types_list`. It doesnt remove generated scope
    # from ActiveRecord models, 'cause it potentialy can remove other methods.
    def unregister_type
      types_list.delete self
    end

    # Shortcut to eager load all descendants.
    def eager_load_types!(dir = nil)
      dir ||= "#{Rails.root}/app/models/#{to_s.underscore}"
      Dir["#{dir}/*.rb"].each { |file| require_dependency file }
    end

    # Tracks all descendants automatically.
    def inherited(base)
      super
      base.register_type
    end

    # Class that was initilly extended with TypesTracker.
    def types_tracker_base
      @_types_tracker_base || superclass.types_tracker_base
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
rails_stuff-0.4.0 lib/rails_stuff/types_tracker.rb