aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/associations
diff options
context:
space:
mode:
authorJon Leighton <j@jonathanleighton.com>2010-10-01 13:10:41 +0100
committerJon Leighton <j@jonathanleighton.com>2010-10-01 13:10:41 +0100
commit4f69a61107d9d59f96bf249ef077483e90babe72 (patch)
tree55ff9b4c472d90b5f7bada4ea1c013a6f847de49 /activerecord/lib/active_record/associations
parent14c4881f9c7bf4eae61e548542ee309c013e1fca (diff)
downloadrails-4f69a61107d9d59f96bf249ef077483e90babe72.tar.gz
rails-4f69a61107d9d59f96bf249ef077483e90babe72.tar.bz2
rails-4f69a61107d9d59f96bf249ef077483e90babe72.zip
Started implementing nested :through associations by using the existing structure of ThroughAssociationScope rather than layering a module over the top
Diffstat (limited to 'activerecord/lib/active_record/associations')
-rw-r--r--activerecord/lib/active_record/associations/has_many_through_association.rb2
-rw-r--r--activerecord/lib/active_record/associations/through_association_scope.rb49
2 files changed, 32 insertions, 19 deletions
diff --git a/activerecord/lib/active_record/associations/has_many_through_association.rb b/activerecord/lib/active_record/associations/has_many_through_association.rb
index 964c381c0d..ee892d373c 100644
--- a/activerecord/lib/active_record/associations/has_many_through_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_through_association.rb
@@ -7,7 +7,7 @@ module ActiveRecord
module Associations
class HasManyThroughAssociation < HasManyAssociation #:nodoc:
include ThroughAssociationScope
- include NestedHasManyThrough
+ # include NestedHasManyThrough
alias_method :new, :build
diff --git a/activerecord/lib/active_record/associations/through_association_scope.rb b/activerecord/lib/active_record/associations/through_association_scope.rb
index cabb33c4a8..c433c9e66e 100644
--- a/activerecord/lib/active_record/associations/through_association_scope.rb
+++ b/activerecord/lib/active_record/associations/through_association_scope.rb
@@ -19,8 +19,8 @@ module ActiveRecord
# Build SQL conditions from attributes, qualified by table name.
def construct_conditions
- table_name = @reflection.through_reflection.quoted_table_name
- conditions = construct_quoted_owner_attributes(@reflection.through_reflection).map do |attr, value|
+ table_name = @reflection.final_through_reflection.quoted_table_name
+ conditions = construct_quoted_owner_attributes(@reflection.final_through_reflection).map do |attr, value|
"#{table_name}.#{attr} = #{value}"
end
conditions << sql_conditions if sql_conditions
@@ -49,35 +49,48 @@ module ActiveRecord
distinct = "DISTINCT " if @reflection.options[:uniq]
selected = custom_select || @reflection.options[:select] || "#{distinct}#{@reflection.quoted_table_name}.*"
end
-
+
def construct_joins(custom_joins = nil)
+ "#{construct_through_joins(@reflection)} #{@reflection.options[:joins]} #{custom_joins}"
+ end
+
+ def construct_through_joins(reflection)
polymorphic_join = nil
- if @reflection.source_reflection.macro == :belongs_to
- reflection_primary_key = @reflection.klass.primary_key
- source_primary_key = @reflection.source_reflection.primary_key_name
- if @reflection.options[:source_type]
+ if reflection.source_reflection.macro == :belongs_to
+ reflection_primary_key = reflection.klass.primary_key
+ source_primary_key = reflection.source_reflection.primary_key_name
+ if reflection.options[:source_type]
polymorphic_join = "AND %s.%s = %s" % [
- @reflection.through_reflection.quoted_table_name, "#{@reflection.source_reflection.options[:foreign_type]}",
- @owner.class.quote_value(@reflection.options[:source_type])
+ reflection.through_reflection.quoted_table_name, "#{@reflection.source_reflection.options[:foreign_type]}",
+ @owner.class.quote_value(reflection.options[:source_type])
]
end
else
- reflection_primary_key = @reflection.source_reflection.primary_key_name
- source_primary_key = @reflection.through_reflection.klass.primary_key
- if @reflection.source_reflection.options[:as]
+ reflection_primary_key = reflection.source_reflection.primary_key_name
+ source_primary_key = reflection.through_reflection.klass.primary_key
+ if reflection.source_reflection.options[:as]
polymorphic_join = "AND %s.%s = %s" % [
- @reflection.quoted_table_name, "#{@reflection.source_reflection.options[:as]}_type",
- @owner.class.quote_value(@reflection.through_reflection.klass.name)
+ reflection.quoted_table_name, "#{@reflection.source_reflection.options[:as]}_type",
+ @owner.class.quote_value(reflection.through_reflection.klass.name)
]
end
end
- "INNER JOIN %s ON %s.%s = %s.%s %s #{@reflection.options[:joins]} #{custom_joins}" % [
- @reflection.through_reflection.quoted_table_name,
- @reflection.quoted_table_name, reflection_primary_key,
- @reflection.through_reflection.quoted_table_name, source_primary_key,
+ joins = "INNER JOIN %s ON %s.%s = %s.%s %s" % [
+ reflection.through_reflection.quoted_table_name,
+ reflection.quoted_table_name, reflection_primary_key,
+ reflection.through_reflection.quoted_table_name, source_primary_key,
polymorphic_join
]
+
+ # If the reflection we are going :through goes itself :through another reflection, then
+ # we must recursively get the joins to make that happen too.
+ if reflection.through_reflection.through_reflection
+ joins << " "
+ joins << construct_through_joins(reflection.through_reflection)
+ end
+
+ joins
end
# Construct attributes for associate pointing to owner.