aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2014-09-02 10:34:10 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2014-09-02 10:34:10 -0700
commit00775e7db5d728e8109ac8e613e7e0bbad929523 (patch)
treef960c7a94b80abc9cf8dcbe22a5a66c87a41cbd3
parent4e7e29d2fd719c756160aa187a40b58413c7db12 (diff)
parent8e9e424fa99769b86c1d3df958ef534868543316 (diff)
downloadrails-00775e7db5d728e8109ac8e613e7e0bbad929523.tar.gz
rails-00775e7db5d728e8109ac8e613e7e0bbad929523.tar.bz2
rails-00775e7db5d728e8109ac8e613e7e0bbad929523.zip
Merge pull request #16762 from eileencodes/refactor-add_constraints-complex-loop-conditional
Refactor add_constraints complex loop conditional
-rw-r--r--activerecord/lib/active_record/associations/association_scope.rb87
1 files changed, 52 insertions, 35 deletions
diff --git a/activerecord/lib/active_record/associations/association_scope.rb b/activerecord/lib/active_record/associations/association_scope.rb
index 4c47af8cb0..26fed22b4c 100644
--- a/activerecord/lib/active_record/associations/association_scope.rb
+++ b/activerecord/lib/active_record/associations/association_scope.rb
@@ -45,20 +45,20 @@ module ActiveRecord
end
def self.get_bind_values(owner, chain)
- bvs = []
- chain.each_with_index do |reflection, i|
- if reflection == chain.last
- bvs << reflection.join_id_for(owner)
- if reflection.type
- bvs << owner.class.base_class.name
- end
- else
- if reflection.type
- bvs << chain[i + 1].klass.base_class.name
- end
+ binds = []
+ last_reflection = chain.last
+
+ binds << last_reflection.join_id_for(owner)
+ if last_reflection.type
+ binds << owner.class.base_class.name
+ end
+
+ chain.each_cons(2).each do |reflection, next_reflection|
+ if reflection.type
+ binds << next_reflection.klass.base_class.name
end
end
- bvs
+ binds
end
private
@@ -96,38 +96,55 @@ module ActiveRecord
bind_value scope, column, value, tracker
end
+ def last_chain_scope(scope, table, reflection, owner, tracker, assoc_klass)
+ join_keys = reflection.join_keys(assoc_klass)
+ key = join_keys.key
+ foreign_key = join_keys.foreign_key
+
+ bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
+ scope = scope.where(table[key].eq(bind_val))
+
+ if reflection.type
+ value = owner.class.base_class.name
+ bind_val = bind scope, table.table_name, reflection.type, value, tracker
+ scope = scope.where(table[reflection.type].eq(bind_val))
+ else
+ scope
+ end
+ end
+
+ def next_chain_scope(scope, table, reflection, chain, tracker, assoc_klass, foreign_table, next_reflection)
+ join_keys = reflection.join_keys(assoc_klass)
+ key = join_keys.key
+ foreign_key = join_keys.foreign_key
+
+ constraint = table[key].eq(foreign_table[foreign_key])
+
+ if reflection.type
+ value = next_reflection.klass.base_class.name
+ bind_val = bind scope, table.table_name, reflection.type, value, tracker
+ scope = scope.where(table[reflection.type].eq(bind_val))
+ end
+
+ scope = scope.joins(join(foreign_table, constraint))
+ end
+
def add_constraints(scope, owner, assoc_klass, refl, tracker)
chain = refl.chain
scope_chain = refl.scope_chain
tables = construct_tables(chain, assoc_klass, refl, tracker)
+ reflection = chain.last
+ table = tables.last
+ scope = last_chain_scope(scope, table, reflection, owner, tracker, assoc_klass)
+
chain.each_with_index do |reflection, i|
table, foreign_table = tables.shift, tables.first
- join_keys = reflection.join_keys(assoc_klass)
- key = join_keys.key
- foreign_key = join_keys.foreign_key
-
- if reflection == chain.last
- bind_val = bind scope, table.table_name, key.to_s, owner[foreign_key], tracker
- scope = scope.where(table[key].eq(bind_val))
-
- if reflection.type
- value = owner.class.base_class.name
- bind_val = bind scope, table.table_name, reflection.type, value, tracker
- scope = scope.where(table[reflection.type].eq(bind_val))
- end
- else
- constraint = table[key].eq(foreign_table[foreign_key])
-
- if reflection.type
- value = chain[i + 1].klass.base_class.name
- bind_val = bind scope, table.table_name, reflection.type, value, tracker
- scope = scope.where(table[reflection.type].eq(bind_val))
- end
-
- scope = scope.joins(join(foreign_table, constraint))
+ unless reflection == chain.last
+ next_reflection = chain[i + 1]
+ scope = next_chain_scope(scope, table, reflection, chain, tracker, assoc_klass, foreign_table, next_reflection)
end
is_first_chain = i == 0