Sha256: bc73229cd97ba3310477ca13772608021d922cbad6985eee6c1260fc23e5d7c5

Contents?: true

Size: 1.71 KB

Versions: 3

Compression:

Stored size: 1.71 KB

Contents

# frozen_string_literal: true

#   Usage:
#
#     klass = AnonymousActiveRecord.generate(columns: ['name']) do
#               def flowery_name
#                 "🌸#{name}🌸"
#               end
#             end
#     instance = klass.new(name: 'Darla Charla')
#     instance.save!
#     instance.flowery_name # => "🌸Darla Charla🌸"
#
module AnonymousActiveRecord
  # Generator defines a pseudo anonymous class in a particular namespace of your choosing.
  class Generator
    DEFAULT_NAME = 'anons'

    attr_reader :klass_namespaces, :table_name, :klass_name, :parent_klass

    def initialize(table_name, klass_namespaces = [], klass_basename = nil, parent_klass = 'ActiveRecord::Base')
      @klass_namespaces = Array(klass_namespaces).map(&:to_s).map { |x| x.gsub(/[^a-z0-9]+/i, '_') }
      klass_context = [(klass_basename || DEFAULT_NAME).gsub(/[^a-z0-9]+/i, '_').capitalize,
                       SecureRandom.uuid.gsub(/[^a-z0-9]+/i, '_')].join('_')
      @table_name = (table_name || klass_context).downcase.to_s
      # String#capitalize is Ruby >= 2.4, https://stackoverflow.com/a/3725154/213191
      @klass_name = (klass_namespaces << klass_context).join('::')
      @parent_klass = parent_klass
    end

    def generate(&block)
      # Many moons ago, ActiveRecord allowed anonymous classes to be created like:
      #   Class.new(ActiveRecord::Base)
      # which was useful for specs, and other use cases.  But it is now explicitly not supported, see
      #   https://github.com/rails/rails/issues/8934
      eval "class ::#{klass_name} < #{parent_klass}; end"
      klass = Kernel.const_get(klass_name, true)
      klass.class_eval(&block) if block
      klass.table_name = table_name
      klass
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
anonymous_active_record-1.0.8 lib/anonymous_active_record/generator.rb
anonymous_active_record-1.0.7 lib/anonymous_active_record/generator.rb
anonymous_active_record-1.0.6 lib/anonymous_active_record/generator.rb