Sha256: fbdc18b6fe217d945c551bad5ddd4c685aadb1da2ee11db9615c6959999e9373

Contents?: true

Size: 1.71 KB

Versions: 1

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

1 entries across 1 versions & 1 rubygems

Version Path
anonymous_active_record-1.0.9 lib/anonymous_active_record/generator.rb