aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/preloader
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2012-07-06 18:20:20 +0100
committerJon Leighton <j@jonathanleighton.com>2012-07-13 16:23:06 +0100
commit65843e1acc0c8d285ff79f8c9c49d4d1215440be (patch)
tree57b18ebd21fe659d82476bb435c04de9964ca308 /activerecord/lib/active_record/associations/preloader
parent76d33970612383c8a3c3a320c544ecbee2f38e1c (diff)
downloadrails-65843e1acc0c8d285ff79f8c9c49d4d1215440be.tar.gz
rails-65843e1acc0c8d285ff79f8c9c49d4d1215440be.tar.bz2
rails-65843e1acc0c8d285ff79f8c9c49d4d1215440be.zip
Represent association scope options as AR::Relations insternally.
Diffstat (limited to 'activerecord/lib/active_record/associations/preloader')
-rw-r--r--activerecord/lib/active_record/associations/preloader/association.rb49
-rw-r--r--activerecord/lib/active_record/associations/preloader/collection_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/has_many_through.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/has_one.rb2
-rw-r--r--activerecord/lib/active_record/associations/preloader/through_association.rb27
5 files changed, 36 insertions, 46 deletions
diff --git a/activerecord/lib/active_record/associations/preloader/association.rb b/activerecord/lib/active_record/associations/preloader/association.rb
index b4c3908b10..e7fd72994f 100644
--- a/activerecord/lib/active_record/associations/preloader/association.rb
+++ b/activerecord/lib/active_record/associations/preloader/association.rb
@@ -2,16 +2,16 @@ module ActiveRecord
module Associations
class Preloader
class Association #:nodoc:
- attr_reader :owners, :reflection, :preload_options, :model, :klass
-
- def initialize(klass, owners, reflection, preload_options)
- @klass = klass
- @owners = owners
- @reflection = reflection
- @preload_options = preload_options || {}
- @model = owners.first && owners.first.class
- @scoped = nil
- @owners_by_key = nil
+ attr_reader :owners, :reflection, :preload_scope, :model, :klass
+
+ def initialize(klass, owners, reflection, preload_scope)
+ @klass = klass
+ @owners = owners
+ @reflection = reflection
+ @preload_scope = preload_scope
+ @model = owners.first && owners.first.class
+ @scoped = nil
+ @owners_by_key = nil
end
def run
@@ -92,34 +92,29 @@ module ActiveRecord
records_by_owner
end
+ def reflection_scope
+ @reflection_scope ||= reflection.scope ? klass.unscoped.instance_exec(&reflection.scope) : klass.unscoped
+ end
+
def build_scope
scope = klass.unscoped
scope.default_scoped = true
- scope = scope.where(interpolate(options[:conditions]))
- scope = scope.where(interpolate(preload_options[:conditions]))
+ values = reflection_scope.values
+ preload_values = preload_scope.values
- scope = scope.select(preload_options[:select] || options[:select] || table[Arel.star])
- scope = scope.includes(preload_options[:include] || options[:include])
+ scope.where_values = Array(values[:where]) + Array(preload_values[:where])
+ scope.references_values = Array(values[:references]) + Array(preload_values[:references])
+
+ scope.select! preload_values[:select] || values[:select] || table[Arel.star]
+ scope.includes! preload_values[:includes] || values[:includes]
if options[:as]
- scope = scope.where(
- klass.table_name => {
- reflection.type => model.base_class.sti_name
- }
- )
+ scope.where!(klass.table_name => { reflection.type => model.base_class.sti_name })
end
scope
end
-
- def interpolate(conditions)
- if conditions.respond_to?(:to_proc)
- klass.send(:instance_eval, &conditions)
- else
- conditions
- end
- 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 c248aeaaf6..e6cd35e7a1 100644
--- a/activerecord/lib/active_record/associations/preloader/collection_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/collection_association.rb
@@ -6,7 +6,7 @@ module ActiveRecord
private
def build_scope
- super.order(preload_options[:order] || options[:order])
+ super.order(preload_scope.values[:order] || reflection_scope.values[:order])
end
def preload
diff --git a/activerecord/lib/active_record/associations/preloader/has_many_through.rb b/activerecord/lib/active_record/associations/preloader/has_many_through.rb
index c6e9ede356..9a662d3f53 100644
--- a/activerecord/lib/active_record/associations/preloader/has_many_through.rb
+++ b/activerecord/lib/active_record/associations/preloader/has_many_through.rb
@@ -6,7 +6,7 @@ module ActiveRecord
def associated_records_by_owner
super.each do |owner, records|
- records.uniq! if options[:uniq]
+ records.uniq! if reflection_scope.uniq_value
end
end
end
diff --git a/activerecord/lib/active_record/associations/preloader/has_one.rb b/activerecord/lib/active_record/associations/preloader/has_one.rb
index 848448bb48..24728e9f01 100644
--- a/activerecord/lib/active_record/associations/preloader/has_one.rb
+++ b/activerecord/lib/active_record/associations/preloader/has_one.rb
@@ -14,7 +14,7 @@ module ActiveRecord
private
def build_scope
- super.order(preload_options[:order] || options[:order])
+ super.order(preload_scope.values[:order] || reflection_scope.values[:order])
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 ad6374d09a..1c1ba11c44 100644
--- a/activerecord/lib/active_record/associations/preloader/through_association.rb
+++ b/activerecord/lib/active_record/associations/preloader/through_association.rb
@@ -14,10 +14,7 @@ module ActiveRecord
def associated_records_by_owner
through_records = through_records_by_owner
- ActiveRecord::Associations::Preloader.new(
- through_records.values.flatten,
- source_reflection.name, options
- ).run
+ Preloader.new(through_records.values.flatten, source_reflection.name, reflection_scope).run
through_records.each do |owner, records|
records.map! { |r| r.send(source_reflection.name) }.flatten!
@@ -28,10 +25,7 @@ module ActiveRecord
private
def through_records_by_owner
- ActiveRecord::Associations::Preloader.new(
- owners, through_reflection.name,
- through_options
- ).run
+ Preloader.new(owners, through_reflection.name, through_scope).run
Hash[owners.map do |owner|
through_records = Array.wrap(owner.send(through_reflection.name))
@@ -45,21 +39,22 @@ module ActiveRecord
end]
end
- def through_options
- through_options = {}
+ def through_scope
+ through_scope = through_reflection.klass.unscoped
if options[:source_type]
- through_options[:conditions] = { reflection.foreign_type => options[:source_type] }
+ through_scope.where! reflection.foreign_type => options[:source_type]
else
- if options[:conditions]
- through_options[:include] = options[:include] || options[:source]
- through_options[:conditions] = options[:conditions]
+ unless reflection_scope.where_values.empty?
+ through_scope.includes_values = reflection_scope.values[:includes] || options[:source]
+ through_scope.where_values = reflection_scope.values[:where]
end
- through_options[:order] = options[:order]
+ through_scope.order! reflection_scope.values[:order]
+ through_scope.references! reflection_scope.values[:references]
end
- through_options
+ through_scope
end
end
end