Sha256: 47ce362192c58608398b97bd734319b12d996ddced3421e3baef5f5b51760abc

Contents?: true

Size: 2 KB

Versions: 1

Compression:

Stored size: 2 KB

Contents

require 'pry'
module Exposant
  module Model
    extend ActiveSupport::Concern

    def exposant(variant = nil, type = nil)
      self.class.exposant_class(variant, type).new(self)
    end

    module ClassMethods
      def has_exposant(name: nil, type: nil)
        @exposant_class = name
        @exposant_type = type

        if type.present? && type != :exposant
          raise 'Type must be a symbol' unless type.is_a?(Symbol)

          define_method type do |variant = nil|
            exposant(variant, type)
          end

          define_singleton_method type do |obj, variant = nil|
            exposant(obj, variant, type)
          end
        end

        self
      end

      def exposant_type
        @exposant_type || :exposant
      end

      def exposant(obj, variant = nil, type = nil)
        obj.extend(ExposantMethods)
        obj.model_klass = self

        if type.present? && type != :exposant
          raise 'Type must be a symbol' unless type.is_a?(Symbol)

          obj.singleton_class.class_eval do
            define_method type do |var = nil|
              exposant(var, type)
            end
          end
        end

        obj.exposant(variant, type)
      end

      def exposant_class(variant = nil, type = nil)
        type_name = (type || exposant_type).to_s.camelcase
        klass = if @exposant_class.present?
                  @exposant_class
                else
                  name.dup.concat(type_name)
                end

        klass = klass
                .split('::')
                .tap { |arr| arr.last.prepend(variant&.to_s&.downcase&.capitalize || '') }
                .join('::')

        raise "Missing exposant #{klass}" unless const_defined?(klass)

        klass.constantize
      end
    end
  end

  module ExposantMethods
    attr_accessor :model_klass

    def exposant(variant = nil, type = nil)
      exposant_class(variant, type).new(self)
    end

    def exposant_class(variant = nil, type = nil)
      model_klass.exposant_class(variant, type)
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
exposant-0.2.0 lib/exposant/model.rb