module RemoteDb module Concerns module Configurable extend ActiveSupport::Concern class ForbiddenActionException < Exception; end module ClassMethods def configure(config_hash = nil) if config_hash config_hash.each do |k,v| setter = "#{k}=" if configuration.respond_to?(setter ) configuration.send(setter , v) end end end yield(configuration) if block_given? end def configuration @configuration ||= RemoteDb::Configuration.new end def without_readonly raise ForbiddenActionException unless configuration.environment == :test load_models!(readonly: false) yield load_models!(readonly: true) end def load_models!(options = { readonly: true }) clear_old_models define_base_record(options) send(:require_models) if respond_to?(:require_models) end private def clear_old_models if self.const_defined? 'BaseRecord' self.const_get('BaseRecord').clear_all_connections! end (self.constants - [:VERSION, :ClassMethods, :ForbiddenActionException]).each do |const| self.send :remove_const, const end end def define_base_record(options) module_name = self.name connection_spec = configuration.connection_spec klass = Class.new(ActiveRecord::Base) do self.abstract_class = true # AR 4 requires AR models to be named. define_singleton_method(:name) { "#{module_name}::BaseRecord" } # Connect via custom db settings establish_connection(connection_spec) # Force model to be ready-only if options[:readonly] include Concerns::ReadOnlyModel end # Scope which columns are exposed include Concerns::RestrictedColumns end self.const_set 'BaseRecord', klass end end end end end