Simplify Preloader#grouped_records code.

The new method relies on AR::Associations::Association knowing about both reflection and a model class.

AR::Base#association now raises a descriptive error when trying to access non-existent associations. Previously it would blow up with a confusing NoMethodError: undefined method `association_class' for nil:NilClass.
This commit is contained in:
thedarkone 2014-03-30 20:52:01 +02:00
parent de32d972bf
commit 055942d6c5
3 changed files with 17 additions and 25 deletions

@ -4,6 +4,12 @@
require 'active_record/errors'
module ActiveRecord
class AssociationNotFoundError < ConfigurationError #:nodoc:
def initialize(record, association_name)
super("Association named '#{association_name}' was not found on #{record.class.name}; perhaps you misspelled it?")
end
end
class InverseOfAssociationNotFoundError < ActiveRecordError #:nodoc:
def initialize(reflection, associated_class = nil)
super("Could not find the inverse association for #{reflection.name} (#{reflection.options[:inverse_of].inspect} in #{associated_class.nil? ? reflection.class_name : associated_class.name})")
@ -145,7 +151,7 @@ def association(name) #:nodoc:
association = association_instance_get(name)
if association.nil?
reflection = self.class.reflect_on_association(name)
raise AssociationNotFoundError.new(self, name) unless reflection = self.class.reflect_on_association(name)
association = reflection.association_class.new(self, reflection)
association_instance_set(name, association)
end

@ -140,27 +140,13 @@ def preloaders_for_one(association, records, scope)
end
def grouped_records(association, records)
reflection_records = records_by_reflection(association, records)
reflection_records.each_with_object({}) do |(reflection, r_records),h|
h[reflection] = r_records.group_by { |record|
record.association(association).klass
}
h = {}
records.each do |record|
assoc = record.association(association)
klasses = h[assoc.reflection] ||= {}
(klasses[assoc.klass] ||= []) << record
end
end
def records_by_reflection(association, records)
records.group_by do |record|
reflection = record.class.reflect_on_association(association)
reflection || raise_config_error(record, association)
end
end
def raise_config_error(record, association)
raise ActiveRecord::ConfigurationError,
"Association named '#{association}' was not found on #{record.class.name}; " \
"perhaps you misspelled it?"
h
end
class AlreadyLoaded

@ -720,16 +720,16 @@ def test_eager_with_multi_table_conditional_properly_counts_the_records_when_usi
end
def test_eager_with_invalid_association_reference
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
Post.all.merge!(:includes=> :monkeys ).find(6)
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
Post.all.merge!(:includes=>[ :monkeys ]).find(6)
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys") {
Post.all.merge!(:includes=>[ 'monkeys' ]).find(6)
}
assert_raise(ActiveRecord::ConfigurationError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
assert_raise(ActiveRecord::AssociationNotFoundError, "Association was not found; perhaps you misspelled it? You specified :include => :monkeys, :elephants") {
Post.all.merge!(:includes=>[ :monkeys, :elephants ]).find(6)
}
end