aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations/through_association.rb
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2011-03-10 19:04:00 +0000
committerJon Leighton <j@jonathanleighton.com>2011-03-10 19:04:00 +0000
commit6490d65234b89d4d28308b72b13d4834fd44bbb3 (patch)
tree4a643e149574251dd16ea479d593260588900518 /activerecord/lib/active_record/associations/through_association.rb
parent67b17d029a8eeddd908cce2d4e0e27e4708e8463 (diff)
downloadrails-6490d65234b89d4d28308b72b13d4834fd44bbb3.tar.gz
rails-6490d65234b89d4d28308b72b13d4834fd44bbb3.tar.bz2
rails-6490d65234b89d4d28308b72b13d4834fd44bbb3.zip
Move the code which builds a scope for through associations into a generic AssociationScope class which is capable of building a scope for any association.
Diffstat (limited to 'activerecord/lib/active_record/associations/through_association.rb')
-rw-r--r--activerecord/lib/active_record/associations/through_association.rb128
1 files changed, 0 insertions, 128 deletions
diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb
index ae2c8b65ed..408237c689 100644
--- a/activerecord/lib/active_record/associations/through_association.rb
+++ b/activerecord/lib/active_record/associations/through_association.rb
@@ -1,5 +1,3 @@
-require 'enumerator'
-
module ActiveRecord
# = Active Record Through Association
module Associations
@@ -26,77 +24,8 @@ module ActiveRecord
scope
end
- def association_scope
- scope = join_to(super)
-
- unless options[:include]
- scope = scope.includes(source_options[:include])
- end
-
- scope
- end
-
private
- # This scope affects the creation of the associated records (not the join records). At the
- # moment we only support creating on a :through association when the source reflection is a
- # belongs_to. Thus it's not necessary to set a foreign key on the associated record(s), so
- # this scope has can legitimately be empty.
- def creation_attributes
- { }
- end
-
- # TODO: Needed?
- def aliased_through_table
- name = through_reflection.table_name
-
- reflection.table_name == name ?
- through_reflection.klass.arel_table.alias(name + "_join") :
- through_reflection.klass.arel_table
- end
-
- def construct_owner_conditions
- end
-
- def join_to(scope)
- joins = []
- tables = tables().dup # FIXME: Ugly
-
- through_reflection_chain.each_with_index do |reflection, i|
- table, foreign_table = tables.shift, tables.first
-
- if reflection.source_macro == :has_and_belongs_to_many
- join_table = tables.shift
-
- joins << inner_join(
- join_table,
- table[reflection.active_record_primary_key].
- eq(join_table[reflection.association_foreign_key])
- )
-
- table, foreign_table = join_table, tables.first
- end
-
- if reflection.source_macro == :belongs_to
- key = reflection.association_primary_key
- foreign_key = reflection.foreign_key
- else
- key = reflection.foreign_key
- foreign_key = reflection.active_record_primary_key
- end
-
- if reflection == through_reflection_chain.last
- constraint = table[key].eq owner[foreign_key]
- scope = scope.where(constraint).where(reflection_conditions(i))
- else
- constraint = table[key].eq foreign_table[foreign_key]
- joins << inner_join(foreign_table, constraint, reflection_conditions(i))
- end
- end
-
- scope.joins(joins)
- end
-
# Construct attributes for :through pointing to owner and associate. This is used by the
# methods which create and delete records on the association.
#
@@ -133,63 +62,6 @@ module ActiveRecord
end
end
- def alias_tracker
- @alias_tracker ||= AliasTracker.new
- end
-
- def tables
- @tables ||= begin
- tables = []
- through_reflection_chain.each do |reflection|
- tables << alias_tracker.aliased_table_for(
- reflection.table_name,
- table_alias_for(reflection, reflection != self.reflection)
- )
-
- if reflection.macro == :has_and_belongs_to_many ||
- (reflection.source_reflection &&
- reflection.source_reflection.macro == :has_and_belongs_to_many)
-
- tables << alias_tracker.aliased_table_for(
- (reflection.source_reflection || reflection).options[:join_table],
- table_alias_for(reflection, true)
- )
- end
- end
- tables
- end
- end
-
- def table_alias_for(reflection, join = false)
- name = alias_tracker.pluralize(reflection.name)
- name << "_#{self.reflection.name}"
- name << "_join" if join
- name
- end
-
- def inner_join(table, *conditions)
- table.create_join(
- table,
- table.create_on(table.create_and(conditions.flatten.compact)))
- end
-
- def reflection_conditions(index)
- reflection = through_reflection_chain[index]
- conditions = through_conditions[index]
-
- unless conditions.empty?
- Arel::Nodes::And.new(process_conditions(conditions, reflection))
- end
- end
-
- def process_conditions(conditions, reflection)
- conditions.map do |condition|
- condition = reflection.klass.send(:sanitize_sql, interpolate(condition), reflection.table_name)
- condition = Arel.sql(condition) unless condition.is_a?(Arel::Node)
- condition
- end
- end
-
# TODO: Think about this in the context of nested associations
def stale_state
if through_reflection.macro == :belongs_to