class DelegateCached::CachedAttribute

Attributes

options[R]
source[R]
target[R]

Public Class Methods

new(model, attribute, reflection, options) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 10
def initialize(model, attribute, reflection, options)
  @options = options
  @source = source_model_data(model, attribute, reflection, options)

  inverse = nil
  if reflection.polymorphic?
    @options[:polymorphic] = true
  else
    inverse = reflection.inverse_of
    inverse ||= retrieve_reflection(options[:inverse_of])
    @options[:skip_callback] = true if inverse.nil?
  end

  @target = target_model_data(attribute, reflection, inverse)

  @source_installer = SourceInstaller.new(@source, @target, options)
  @target_installer = TargetInstaller.new(@source, @target, options)
end

Public Instance Methods

install!() click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 29
def install!
  validate
  @source_installer.install_instance_methods
  @target_installer.install_instance_methods
end

Protected Instance Methods

missing_attribute(model, attribute) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 89
def missing_attribute(model, attribute)
  message = "WARNING: `#{attribute}' is not an attribute of `#{model}'." \
            'This may happen before or during migrations when your column' \
            'has not yet been created.'

  if defined?(Rails)
    Rails.logger.warn message
  else
    STDERR.puts message
  end
end
retrieve_reflection(inverse_of) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 51
def retrieve_reflection(inverse_of)
  @source.reflection.klass.reflect_on_association(inverse_of)
end
source_column_name(attribute, options) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 101
def source_column_name(attribute, options)
  return attribute.to_s unless options[:prefix]
  "#{options[:to]}_#{attribute}"
end
source_model_data(model, attribute, reflection, options) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 37
def source_model_data(model, attribute, reflection, options)
  ModelData.new(model,
                source_column_name(attribute, options),
                options[:to],
                reflection)
end
target_model_data(attribute, reflection, inverse) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 44
def target_model_data(attribute, reflection, inverse)
  ModelData.new(reflection.class_name.safe_constantize,
                attribute,
                @options[:polymorphic] ? '' : inverse.name,
                inverse)
end
validate() click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 55
def validate
  validate_column_exists(@source.model, @source.column)
  return if @options[:polymorphic]
  validate_column_exists(@target.model, @target.column)
  validate_target_association
end
validate_column_exists(model, column) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 62
def validate_column_exists(model, column)
  # The models cannot be validated if they are preloaded and the
  # attribute/column is not in the database (the migration has not been run)
  # or tables do not exist. This usually occurs in the 'test' and
  # 'production' environment or during migrations.
  return if defined?(Rails) && Rails.configuration.cache_classes ||
            !model.table_exists? || !model.table_exists?

  return if model.columns.detect { |cl| cl.name == column.to_s }
  missing_attribute(model, column)
end
validate_inverse(inverse) click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 74
def validate_inverse(inverse)
  return unless inverse.blank?
  raise ArgumentError,
        "#{@source.association} association on #{@source} " \
        'must either have an :inverse_of or you may pass :inverse_of into' \
        ' delegate_cached.'
end
validate_target_association() click to toggle source
# File lib/delegate_cached/cached_attribute.rb, line 82
def validate_target_association
  return if @target.model.instance_methods.include?(@target.association)
  raise ArgumentError,
        "The #{@target.association} association does not exist on " \
        "#{@target.model}"
end