# frozen_string_literal: true require 'adaptive_alias/version' require 'adaptive_alias/active_model_patches/read_attribute' require 'adaptive_alias/active_model_patches/write_attribute' require 'adaptive_alias/active_model_patches/remove_alias_attribute' require 'adaptive_alias/active_model_patches/apply_scope' require 'adaptive_alias/active_model_patches/arel_table' require 'adaptive_alias/patches/backward_patch' require 'adaptive_alias/patches/forward_patch' require 'adaptive_alias/hooks/association' require 'adaptive_alias/hooks/association_scope' require 'adaptive_alias/hooks/singular_association' require 'adaptive_alias/hooks/relation' require 'adaptive_alias/hooks/active_record_core' require 'adaptive_alias/hooks/active_record_persistence' module AdaptiveAlias @log_interval = 10 * 60 @current_patches = {} @model_modules ||= {} class << self attr_accessor :unexpected_old_column_proc attr_accessor :log_interval attr_accessor :current_patches end class << self def [](old_column, new_column) old_column = old_column.to_sym new_column = new_column.to_sym Module.new do extend ActiveSupport::Concern included do patch = (column_names.include?(new_column.to_s) ? Patches::BackwardPatch : Patches::ForwardPatch).new(self, old_column, new_column) patch.apply! patch.mark_removable end end end def rescue_statement_invalid(relation: nil, reflection: nil, model: nil, &block) yield rescue ActiveRecord::StatementInvalid => error raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_association.call(relation, reflection, model, error) } result = rescue_statement_invalid(relation: relation, reflection: reflection, model: model, &block) AdaptiveAlias.current_patches.each_value(&:mark_removable) return result end def rescue_missing_attribute(klass, &block) yield rescue ActiveModel::MissingAttributeError => error raise error if AdaptiveAlias.current_patches.all?{|_key, patch| !patch.fix_missing_attribute.call(klass, error) } result = rescue_missing_attribute(klass, &block) AdaptiveAlias.current_patches.each_value(&:mark_removable) return result end def get_or_create_model_module(klass) return @model_modules[klass] if @model_modules[klass] @model_modules[klass] = Module.new klass.prepend(@model_modules[klass]) return @model_modules[klass] end end end