Class: ActiveRecord::Base
- Extended by:
- Associations::PolymorphicClassMethods
- Defined in:
- lib/has_many_polymorphs/base.rb,
lib/has_many_polymorphs/support_methods.rb,
lib/has_many_polymorphs.rb
Constant Summary collapse
- COLLECTION_METHODS =
[:belongs_to, :has_many, :has_and_belongs_to_many, :has_one, :has_many_polymorphs, :acts_as_double_polymorphic_join].each do |method_name| alias_method "original_#{method_name}".to_sym, method_name undef_method method_name end
- GENERATED_CODE_DIR =
"#{base_dir}/generated_models"
Constants included from Associations::PolymorphicClassMethods
Associations::PolymorphicClassMethods::RESERVED_DOUBLES_KEYS
Class Method Summary collapse
-
.instantiate_with_polymorphic_checks(record) ⇒ Object
Interprets a polymorphic row from a unified SELECT, returning the appropriate ActiveRecord instance.
Instance Method Summary collapse
-
#_base_class_name ⇒ Object
Return the base class name as a string.
- #method_missing(method_name, *args, &block) ⇒ Object
- #original_method_missing ⇒ Object
Methods included from Associations::PolymorphicClassMethods
acts_as_double_polymorphic_join, create_has_many_polymorphs_reflection, has_many_polymorphs
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &block) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# 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 |
Class Method Details
.instantiate_with_polymorphic_checks(record) ⇒ Object
Interprets a polymorphic row from a unified SELECT, returning the appropriate ActiveRecord instance. Overrides ActiveRecord::Base.instantiate_without_callbacks.
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/has_many_polymorphs/base.rb', line 7 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.[: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.[: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 child_id = record["#{self.table_name}.#{reflection.[:polymorphic_key]}"] unless child_id == record["#{klass.table_name}.#{klass.primary_key}"] msg = [] msg << "Referential integrity violation" msg << "child <#{klass.name}:#{child_id}> was not found for #{reflection.name.inspect}" raise ActiveRecord::Associations::PolymorphicError, msg.join('; ') end # eject the join keys # XXX not very readable record = Hash[*record._select do |column, value| column[/^#{klass.table_name}/] end.map do |column, value| [column[/\.(.*)/, 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 |
Instance Method Details
#_base_class_name ⇒ Object
Return the base class name as a string.
86 87 88 |
# File 'lib/has_many_polymorphs/support_methods.rb', line 86 def _base_class_name self.class.base_class.name.to_s end |
#original_method_missing ⇒ Object
55 |
# File 'lib/has_many_polymorphs/debugging_tools.rb', line 55 alias :original_method_missing :method_missing |