class Paperclip::HasAttachedFile

def self.define_on(klass, name, options)

def self.define_on(klass, name, options)
  new(klass, name, options).define
end

def add_active_record_callbacks

def add_active_record_callbacks
  name = @name
  @klass.send(:after_save) { send(name).send(:save) }
  @klass.send(:before_destroy) { send(name).send(:queue_all_for_delete) }
  if @klass.respond_to?(:after_commit)
    @klass.send(:after_commit, on: :destroy) do
      send(name).send(:flush_deletes)
    end
  else
    @klass.send(:after_destroy) { send(name).send(:flush_deletes) }
  end
end

def add_paperclip_callbacks

def add_paperclip_callbacks
  @klass.send(
    :define_paperclip_callbacks,
    :post_process, :"#{@name}_post_process")
end

def add_required_validations

def add_required_validations
  options = Paperclip::Attachment.default_options.deep_merge(@options)
  if options[:validate_media_type] != false
    name = @name
    @klass.validates_media_type_spoof_detection name,
      :if => ->(instance){ instance.send(name).dirty? }
  end
end

def define

def define
  define_flush_errors
  define_getters
  define_setter
  define_query
  register_new_attachment
  add_active_record_callbacks
  add_paperclip_callbacks
  add_required_validations
end

def define_class_getter

def define_class_getter
  @klass.extend(ClassMethods)
end

def define_flush_errors

def define_flush_errors
  @klass.send(:validates_each, @name) do |record, attr, value|
    attachment = record.send(@name)
    attachment.send(:flush_errors)
  end
end

def define_getters

def define_getters
  define_instance_getter
  define_class_getter
end

def define_instance_getter

def define_instance_getter
  name = @name
  options = @options
  @klass.send :define_method, @name do |*args|
    ivar = "@attachment_#{name}"
    attachment = instance_variable_get(ivar)
    if attachment.nil?
      attachment = Attachment.new(name, self, options)
      instance_variable_set(ivar, attachment)
    end
    if args.length > 0
      attachment.to_s(args.first)
    else
      attachment
    end
  end
end

def define_query

def define_query
  name = @name
  @klass.send :define_method, "#{@name}?" do
    send(name).file?
  end
end

def define_setter

def define_setter
  name = @name
  @klass.send :define_method, "#{@name}=" do |file|
    send(name).assign(file)
  end
end

def initialize(klass, name, options)

def initialize(klass, name, options)
  @klass = klass
  @name = name
  @options = options
end

def register_new_attachment

def register_new_attachment
  Paperclip::AttachmentRegistry.register(@klass, @name, @options)
end