aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/CHANGELOG.md19
-rw-r--r--activerecord/lib/active_record/associations/join_dependency.rb5
-rw-r--r--activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb19
3 files changed, 41 insertions, 2 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 3c4f06ccf8..5aa905038d 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,22 @@
+* Includes HABTM returns correct size now. It's caused by the join dependency
+ only instantiates one HABTM object because the join table hasn't a primary key.
+
+ Fixes #16032.
+
+ Examples:
+
+ before:
+
+ Project.first.salaried_developers.size # => 3
+ Project.includes(:salaried_developers).first.salaried_developers.size # => 1
+
+ after:
+
+ Project.first.salaried_developers.size # => 3
+ Project.includes(:salaried_developers).first.salaried_developers.size # => 3
+
+ *Bigxiang*
+
* Fix accessing of fixtures having non-string labels like Fixnum.
*Prathamesh Sonpatki*
diff --git a/activerecord/lib/active_record/associations/join_dependency.rb b/activerecord/lib/active_record/associations/join_dependency.rb
index 4b75370171..85febcc771 100644
--- a/activerecord/lib/active_record/associations/join_dependency.rb
+++ b/activerecord/lib/active_record/associations/join_dependency.rb
@@ -150,7 +150,8 @@ module ActiveRecord
message_bus.instrument('instantiation.active_record', payload) do
result_set.each { |row_hash|
- parent = parents[row_hash[primary_key]] ||= join_root.instantiate(row_hash, column_aliases)
+ parent_key = primary_key ? row_hash[primary_key] : row_hash
+ parent = parents[parent_key] ||= join_root.instantiate(row_hash, column_aliases)
construct(parent, join_root, row_hash, result_set, seen, model_cache, aliases)
}
end
@@ -232,7 +233,7 @@ module ActiveRecord
end
def construct(ar_parent, parent, row, rs, seen, model_cache, aliases)
- primary_id = ar_parent.id
+ primary_id = ar_parent.id || row
parent.children.each do |node|
if node.reflection.collection?
diff --git a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
index aea9207bfe..fb7630fc4a 100644
--- a/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
+++ b/activerecord/test/cases/associations/has_and_belongs_to_many_associations_test.rb
@@ -902,4 +902,23 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
DeveloperWithSymbolClassName.new
end
end
+
+ def test_preloaded_associations_size
+ assert_equal Project.first.salaried_developers.size,
+ Project.preload(:salaried_developers).first.salaried_developers.size
+
+ assert_equal Project.includes(:salaried_developers).references(:salaried_developers).first.salaried_developers.size,
+ Project.preload(:salaried_developers).first.salaried_developers.size
+
+ # Nested HATBM
+ first_project = Developer.first.projects.first
+ preloaded_first_project =
+ Developer.preload(projects: :salaried_developers).
+ first.
+ projects.
+ detect { |p| p.id == first_project.id }
+
+ assert preloaded_first_project.salaried_developers.loaded?, true
+ assert_equal first_project.salaried_developers.size, preloaded_first_project.salaried_developers.size
+ end
end