class ActiveRecord::Base

Constants

COLLECTION_METHODS
GENERATED_CODE_DIR

Public Instance Methods

_base_class_name() click to toggle source

Return the base class name as a string.

# File lib/has_many_polymorphs/support_methods.rb, line 84
def _base_class_name
  self.class.base_class.name.to_s
end

Public Class Methods

instantiate_with_polymorphic_checks(record) click to toggle source

Interprets a polymorphic row from a unified SELECT, returning the appropriate ActiveRecord instance. Overrides ActiveRecord::Base.instantiate_without_callbacks.

# File lib/has_many_polymorphs/base.rb, line 8
      def instantiate_with_polymorphic_checks(record)
        if record['polymorphic_parent_class']
          reflection = record['polymorphic_parent_class'].constantize.reflect_on_association(record['polymorphic_association_id'].to_sym)
#          _logger_debug "Instantiating a polymorphic row for #{record['polymorphic_parent_class']}.reflect_on_association(:#{record['polymorphic_association_id']})"

          # rewrite the record with the right column names
          table_aliases = reflection.options[:table_aliases].dup
          record = Hash[*table_aliases.keys.map {|key| [key, record[table_aliases[key]]] }.flatten]

          # find the real child class
          klass = record["#{self.table_name}.#{reflection.options[:polymorphic_type_key]}"].constantize
          if sti_klass = record["#{klass.table_name}.#{klass.inheritance_column}"]
            klass = klass.class_eval do compute_type(sti_klass) end # in case of namespaced STI models

            # copy the data over to the right structure
            klass.columns.map(&:name).each do |col|
              record["#{klass.table_name}.#{col}"] = record["#{klass.base_class.table_name}.#{col}"]
            end
          end

          # check that the join actually joined to something
          unless (child_id = record["#{self.table_name}.#{reflection.options[:polymorphic_key]}"]) == record["#{klass.table_name}.#{klass.primary_key}"]
            raise ActiveRecord::Associations::PolymorphicError,
              "Referential integrity violation; child <#{klass.name}:#{child_id}> was not found for #{reflection.name.inspect}"
          end

          # eject the join keys
          # XXX not very readable
          record = Hash[*record._select do |column, value|
            column[%r^#{klass.table_name}/]
          end.map do |column, value|
            [column[%r\.(.*)/, 1], value]
          end.flatten]

          # allocate and assign values
          klass.allocate.tap do |obj|
            obj.instance_variable_set("@attributes", record)
            obj.instance_variable_set("@attributes_cache", Hash.new)

            if obj.respond_to_without_attributes?(:after_find)
              obj.send(:callback, :after_find)
            end

            if obj.respond_to_without_attributes?(:after_initialize)
              obj.send(:callback, :after_initialize)
            end

          end
        else
          instantiate_without_polymorphic_checks(record)
        end
      end
method_missing(method_name, *args, &block) click to toggle source
# File lib/has_many_polymorphs/debugging_tools.rb, line 56
def method_missing(method_name, *args, &block)
  if COLLECTION_METHODS.include? method_name.to_sym
    Dir.chdir GENERATED_CODE_DIR do
      filename = "#{demodulate(self.name.underscore)}.rb"
      contents = File.open(filename).read rescue "\nclass #{self.name}\n\nend\n"
      callfile, callline = caller[2][%r/.*/(.*?:\d+)!, 1].split(':')
      contents[-5..-5] = "\n  #{method_name} #{args[0..-2].inspect[1..-2]},\n     #{args[-1].inspect[1..-2].gsub(" :", "\n     :").gsub("=>", " => ")}\n#{ block ? "     #{block.inspect.sub(/\@.*\//, '@')}\n" : ""}     # called from #{callfile}, line #{callline}\n\n"
      File.open(filename, "w") do |file|
        file.puts contents
      end
    end
    # doesn't actually display block contents
    self.send("original_#{method_name}", *args, &block)
  else
    self.send(:original_method_missing, method_name, *args, &block)
  end
end
Also aliased as: original_method_missing
original_method_missing(method_name, *args, &block) click to toggle source
Alias for: method_missing