aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorPratik Naik <pratiknaik@gmail.com>2008-05-06 12:16:55 +0100
committerPratik Naik <pratiknaik@gmail.com>2008-05-06 12:16:55 +0100
commit63e8bcaeb31443cecc5bef5762a45643cc12d481 (patch)
tree57800132eecace875b1701b79883d179dfb8c021 /activerecord/lib
parent4a0118d7278687b534edf1e1184d6858cb4d29b8 (diff)
parente520fd5db7cb839b862c03647effee50f9223d98 (diff)
downloadrails-63e8bcaeb31443cecc5bef5762a45643cc12d481.tar.gz
rails-63e8bcaeb31443cecc5bef5762a45643cc12d481.tar.bz2
rails-63e8bcaeb31443cecc5bef5762a45643cc12d481.zip
Merge commit 'mainstream/master'
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/association_preload.rb7
-rw-r--r--[-rwxr-xr-x]activerecord/lib/active_record/associations.rb25
2 files changed, 30 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb
index 3e7c787dee..da4ebdef51 100644
--- a/activerecord/lib/active_record/association_preload.rb
+++ b/activerecord/lib/active_record/association_preload.rb
@@ -65,7 +65,13 @@ module ActiveRecord
end
def set_association_single_records(id_to_record_map, reflection_name, associated_records, key)
+ seen_keys = {}
associated_records.each do |associated_record|
+ #this is a has_one or belongs_to: there should only be one record.
+ #Unfortunately we can't (in portable way) ask the database for 'all records where foo_id in (x,y,z), but please
+ # only one row per distinct foo_id' so this where we enforce that
+ next if seen_keys[associated_record[key].to_s]
+ seen_keys[associated_record[key].to_s] = true
mapped_records = id_to_record_map[associated_record[key].to_s]
mapped_records.each do |mapped_record|
mapped_record.send("set_#{reflection_name}_target", associated_record)
@@ -122,7 +128,6 @@ module ActiveRecord
else
records.each {|record| record.send("set_#{reflection.name}_target", nil)}
-
set_association_single_records(id_to_record_map, reflection.name, find_associated_records(ids, reflection, preload_options), reflection.primary_key_name)
end
end
diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb
index 5251a7b0f5..691d938788 100755..100644
--- a/activerecord/lib/active_record/associations.rb
+++ b/activerecord/lib/active_record/associations.rb
@@ -1446,6 +1446,12 @@ module ActiveRecord
tables_from_conditions = conditions_tables(options)
tables_from_order = order_tables(options)
all_tables = tables_from_conditions + tables_from_order
+ distinct_join_associations = all_tables.uniq.map{|table|
+ join_dependency.joins_for_table_name(table)
+ }.flatten.compact.uniq
+
+
+
is_distinct = !options[:joins].blank? || include_eager_conditions?(options, tables_from_conditions) || include_eager_order?(options, tables_from_order)
sql = "SELECT "
@@ -1457,7 +1463,7 @@ module ActiveRecord
sql << " FROM #{connection.quote_table_name table_name} "
if is_distinct
- sql << join_dependency.join_associations.reject{ |ja| !all_tables.include?(ja.table_name) }.collect(&:association_join).join
+ sql << distinct_join_associations.collect(&:association_join).join
add_joins!(sql, options, scope)
end
@@ -1617,6 +1623,23 @@ module ActiveRecord
end
end
+ def join_for_table_name(table_name)
+ @joins.select{|j|j.aliased_table_name == table_name.gsub(/^\"(.*)\"$/){$1} }.first rescue nil
+ end
+
+ def joins_for_table_name(table_name)
+ join = join_for_table_name(table_name)
+ result = nil
+ if join && join.is_a?(JoinAssociation)
+ result = [join]
+ if join.parent && join.parent.is_a?(JoinAssociation)
+ result = joins_for_table_name(join.parent.aliased_table_name) +
+ result
+ end
+ end
+ result
+ end
+
protected
def build(associations, parent = nil)
parent ||= @joins.last