aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/preloader
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/associations/preloader')
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb142
-rw-r--r--activerecord/lib/active_record/associations/preloader/belongs_to.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/collection_association.rb14
-rw-r--r--activerecord/lib/active_record/associations/preloader/has_many.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/singular_association.rb16
-rw-r--r--activerecord/lib/active_record/associations/preloader/through_association.rb63
6 files changed, 116 insertions, 123 deletions
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index 3032bc786e..a8afa48865 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -61,99 +61,99 @@ module ActiveRecord
private
- def associated_records_by_owner(preloader)
- records = load_records
- owners.each_with_object({}) do |owner, result|
- result[owner] = records[convert_key(owner[owner_key_name])] || []
+ def associated_records_by_owner(preloader)
+ records = load_records
+ owners.each_with_object({}) do |owner, result|
+ result[owner] = records[convert_key(owner[owner_key_name])] || []
+ end
end
- end
- def owner_keys
- unless defined?(@owner_keys)
- @owner_keys = owners.map do |owner|
- owner[owner_key_name]
+ def owner_keys
+ unless defined?(@owner_keys)
+ @owner_keys = owners.map do |owner|
+ owner[owner_key_name]
+ end
+ @owner_keys.uniq!
+ @owner_keys.compact!
end
- @owner_keys.uniq!
- @owner_keys.compact!
+ @owner_keys
end
- @owner_keys
- end
- def key_conversion_required?
- @key_conversion_required ||= association_key_type != owner_key_type
- end
+ def key_conversion_required?
+ @key_conversion_required ||= association_key_type != owner_key_type
+ end
- def convert_key(key)
- if key_conversion_required?
- key.to_s
- else
- key
+ def convert_key(key)
+ if key_conversion_required?
+ key.to_s
+ else
+ key
+ end
end
- end
- def association_key_type
- @klass.type_for_attribute(association_key_name.to_s).type
- end
+ def association_key_type
+ @klass.type_for_attribute(association_key_name.to_s).type
+ end
- def owner_key_type
- @model.type_for_attribute(owner_key_name.to_s).type
- end
+ def owner_key_type
+ @model.type_for_attribute(owner_key_name.to_s).type
+ end
- def load_records
- return {} if owner_keys.empty?
- # Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
- # Make several smaller queries if necessary or make one query if the adapter supports it
- slices = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
- @preloaded_records = slices.flat_map do |slice|
- records_for(slice)
+ def load_records
+ return {} if owner_keys.empty?
+ # Some databases impose a limit on the number of ids in a list (in Oracle it's 1000)
+ # Make several smaller queries if necessary or make one query if the adapter supports it
+ slices = owner_keys.each_slice(klass.connection.in_clause_length || owner_keys.size)
+ @preloaded_records = slices.flat_map do |slice|
+ records_for(slice)
+ end
+ @preloaded_records.group_by do |record|
+ convert_key(record[association_key_name])
+ end
end
- @preloaded_records.group_by do |record|
- convert_key(record[association_key_name])
+
+ def reflection_scope
+ @reflection_scope ||= reflection.scope ? klass.unscoped.instance_exec(nil, &reflection.scope) : klass.unscoped
end
- end
- def reflection_scope
- @reflection_scope ||= reflection.scope ? klass.unscoped.instance_exec(nil, &reflection.scope) : klass.unscoped
- end
+ def build_scope
+ scope = klass.unscoped
- def build_scope
- scope = klass.unscoped
+ values = reflection_scope.values
+ preload_values = preload_scope.values
- values = reflection_scope.values
- preload_values = preload_scope.values
+ scope.where_clause = reflection_scope.where_clause + preload_scope.where_clause
+ scope.references_values = Array(values[:references]) + Array(preload_values[:references])
- scope.where_clause = reflection_scope.where_clause + preload_scope.where_clause
- scope.references_values = Array(values[:references]) + Array(preload_values[:references])
+ if preload_values[:select] || values[:select]
+ scope._select!(preload_values[:select] || values[:select])
+ end
+ scope.includes! preload_values[:includes] || values[:includes]
+ if preload_scope.joins_values.any?
+ scope.joins!(preload_scope.joins_values)
+ else
+ scope.joins!(reflection_scope.joins_values)
+ end
- if preload_values[:select] || values[:select]
- scope._select!(preload_values[:select] || values[:select])
- end
- scope.includes! preload_values[:includes] || values[:includes]
- if preload_scope.joins_values.any?
- scope.joins!(preload_scope.joins_values)
- else
- scope.joins!(reflection_scope.joins_values)
- end
+ if order_values = preload_values[:order] || values[:order]
+ scope.order!(order_values)
+ end
- if order_values = preload_values[:order] || values[:order]
- scope.order!(order_values)
- end
+ if preload_values[:reordering] || values[:reordering]
+ scope.reordering_value = true
+ end
- if preload_values[:reordering] || values[:reordering]
- scope.reordering_value = true
- end
+ if preload_values[:readonly] || values[:readonly]
+ scope.readonly!
+ end
- if preload_values[:readonly] || values[:readonly]
- scope.readonly!
- end
+ if options[:as]
+ scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
+ end
- if options[:as]
- scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
+ scope.unscope_values = Array(values[:unscope]) + Array(preload_values[:unscope])
+ klass.default_scoped.merge(scope)
end
-
- scope.unscope_values = Array(values[:unscope]) + Array(preload_values[:unscope])
- klass.default_scoped.merge(scope)
- end
end
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/belongs_to.rb b/activerecord/lib/active_record/associations/preloader/belongs_to.rb
index 5091d4717a..38e231826c 100644
--- a/activerecord/lib/active_record/associations/preloader/belongs_to.rb
+++ b/activerecord/lib/active_record/associations/preloader/belongs_to.rb
@@ -2,7 +2,6 @@ module ActiveRecord
module Associations
class Preloader
class BelongsTo < SingularAssociation #:nodoc:
-
def association_key_name
reflection.options[:primary_key] || klass && klass.primary_key
end
@@ -10,7 +9,6 @@ module ActiveRecord
def owner_key_name
reflection.foreign_key
end
-
end
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/collection_association.rb b/activerecord/lib/active_record/associations/preloader/collection_association.rb
index 9939280fa4..24b8e01029 100644
--- a/activerecord/lib/active_record/associations/preloader/collection_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/collection_association.rb
@@ -4,14 +4,14 @@ module ActiveRecord
class CollectionAssociation < Association #:nodoc:
private
- def preload(preloader)
- associated_records_by_owner(preloader).each do |owner, records|
- association = owner.association(reflection.name)
- association.loaded!
- association.target.concat(records)
- records.each { |record| association.set_inverse_instance(record) }
+ def preload(preloader)
+ associated_records_by_owner(preloader).each do |owner, records|
+ association = owner.association(reflection.name)
+ association.loaded!
+ association.target.concat(records)
+ records.each { |record| association.set_inverse_instance(record) }
+ end
end
- end
end
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/has_many.rb b/activerecord/lib/active_record/associations/preloader/has_many.rb
index 3ea91a8c11..20df1cc19a 100644
--- a/activerecord/lib/active_record/associations/preloader/has_many.rb
+++ b/activerecord/lib/active_record/associations/preloader/has_many.rb
@@ -2,7 +2,6 @@ module ActiveRecord
module Associations
class Preloader
class HasMany < CollectionAssociation #:nodoc:
-
def association_key_name
reflection.foreign_key
end
@@ -10,7 +9,6 @@ module ActiveRecord
def owner_key_name
reflection.active_record_primary_key
end
-
end
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/singular_association.rb b/activerecord/lib/active_record/associations/preloader/singular_association.rb
index f60647a81e..0888d383a6 100644
--- a/activerecord/lib/active_record/associations/preloader/singular_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/singular_association.rb
@@ -2,19 +2,17 @@ module ActiveRecord
module Associations
class Preloader
class SingularAssociation < Association #:nodoc:
-
private
- def preload(preloader)
- associated_records_by_owner(preloader).each do |owner, associated_records|
- record = associated_records.first
+ def preload(preloader)
+ associated_records_by_owner(preloader).each do |owner, associated_records|
+ record = associated_records.first
- association = owner.association(reflection.name)
- association.target = record
- association.set_inverse_instance(record) if record
+ association = owner.association(reflection.name)
+ association.target = record
+ association.set_inverse_instance(record) if record
+ end
end
- end
-
end
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/through_association.rb b/activerecord/lib/active_record/associations/preloader/through_association.rb
index b0203909ce..be9dfe7686 100644
--- a/activerecord/lib/active_record/associations/preloader/through_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/through_association.rb
@@ -61,48 +61,47 @@ module ActiveRecord
private
- def id_to_index_map(ids)
- id_map = {}
- ids.each_with_index { |id, index| id_map[id] = index }
- id_map
- end
+ def id_to_index_map(ids)
+ id_map = {}
+ ids.each_with_index { |id, index| id_map[id] = index }
+ id_map
+ end
- def reset_association(owners, association_name)
- should_reset = (through_scope != through_reflection.klass.unscoped) ||
- (reflection.options[:source_type] && through_reflection.collection?)
+ def reset_association(owners, association_name)
+ should_reset = (through_scope != through_reflection.klass.unscoped) ||
+ (reflection.options[:source_type] && through_reflection.collection?)
- # Don't cache the association - we would only be caching a subset
- if should_reset
- owners.each { |owner|
- owner.association(association_name).reset
- }
+ # Don't cache the association - we would only be caching a subset
+ if should_reset
+ owners.each { |owner|
+ owner.association(association_name).reset
+ }
+ end
end
- end
+ def through_scope
+ scope = through_reflection.klass.unscoped
- def through_scope
- scope = through_reflection.klass.unscoped
+ if options[:source_type]
+ scope.where! reflection.foreign_type => options[:source_type]
+ else
+ unless reflection_scope.where_clause.empty?
+ scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
+ scope.where_clause = reflection_scope.where_clause
+ end
- if options[:source_type]
- scope.where! reflection.foreign_type => options[:source_type]
- else
- unless reflection_scope.where_clause.empty?
- scope.includes_values = Array(reflection_scope.values[:includes] || options[:source])
- scope.where_clause = reflection_scope.where_clause
+ scope.references! reflection_scope.values[:references]
+ if scope.eager_loading? && order_values = reflection_scope.values[:order]
+ scope = scope.order(order_values)
+ end
end
- scope.references! reflection_scope.values[:references]
- if scope.eager_loading? && order_values = reflection_scope.values[:order]
- scope = scope.order(order_values)
- end
+ scope
end
- scope
- end
-
- def target_records_from_association(association)
- association.loaded? ? association.target : association.reader
- end
+ def target_records_from_association(association)
+ association.loaded? ? association.target : association.reader
+ end
end
end
end