diff options
Diffstat (limited to 'activerecord')
9 files changed, 69 insertions, 36 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md index 477bc1b54a..cfc5647969 100644 --- a/activerecord/CHANGELOG.md +++ b/activerecord/CHANGELOG.md @@ -1,3 +1,13 @@ +* Don't update counter cache unless the record is actually saved. + + Fixes #31493, #33113, #33117. + + *Ryuta Kamizono* + +* Deprecate `ActiveRecord::Result#to_hash` in favor of `ActiveRecord::Result#to_a`. + + *Gannon McGibbon*, *Kevin Cheng* + * SQLite3 adapter supports expression indexes. ``` diff --git a/activerecord/lib/active_record/associations/belongs_to_association.rb b/activerecord/lib/active_record/associations/belongs_to_association.rb index 3d4ad1dd5b..544aec5e8b 100644 --- a/activerecord/lib/active_record/associations/belongs_to_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_association.rb @@ -50,11 +50,8 @@ module ActiveRecord def replace(record) if record raise_on_type_mismatch!(record) - update_counters_on_replace(record) set_inverse_instance(record) @updated = true - else - decrement_counters end replace_keys(record) @@ -80,19 +77,6 @@ module ActiveRecord reflection.counter_cache_column && owner.persisted? end - def update_counters_on_replace(record) - if require_counter_update? && different_target?(record) - owner.instance_variable_set :@_after_replace_counter_called, true - record.increment!(reflection.counter_cache_column, touch: reflection.options[:touch]) - decrement_counters - end - end - - # Checks whether record is different to the current target, without loading it - def different_target?(record) - record._read_attribute(primary_key(record)) != owner._read_attribute(reflection.foreign_key) - end - def replace_keys(record) owner[reflection.foreign_key] = record ? record._read_attribute(primary_key(record)) : nil end diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb index 3fd2fb5f67..9ae452e7a1 100644 --- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb @@ -19,10 +19,6 @@ module ActiveRecord owner[reflection.foreign_type] = record ? record.class.polymorphic_name : nil end - def different_target?(record) - super || record.class != klass - end - def inverse_reflection_for(record) reflection.polymorphic_inverse_of(record.class) end diff --git a/activerecord/lib/active_record/associations/builder/belongs_to.rb b/activerecord/lib/active_record/associations/builder/belongs_to.rb index 0166ed98ca..da4cc343eb 100644 --- a/activerecord/lib/active_record/associations/builder/belongs_to.rb +++ b/activerecord/lib/active_record/associations/builder/belongs_to.rb @@ -34,9 +34,7 @@ module ActiveRecord::Associations::Builder # :nodoc: foreign_key = reflection.foreign_key cache_column = reflection.counter_cache_column - if @_after_replace_counter_called ||= false - @_after_replace_counter_called = false - elsif association(reflection.name).target_changed? + if association(reflection.name).target_changed? if reflection.polymorphic? model = attribute_in_database(reflection.foreign_type).try(:constantize) model_was = attribute_before_last_save(reflection.foreign_type).try(:constantize) diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index d32fd5ea09..baa0a29afd 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -576,7 +576,7 @@ module ActiveRecord column end else - basic_structure.to_hash + basic_structure.to_a end end diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb index 3b2556b1c8..da6d10b6ec 100644 --- a/activerecord/lib/active_record/result.rb +++ b/activerecord/lib/active_record/result.rb @@ -21,7 +21,7 @@ module ActiveRecord # ] # # # Get an array of hashes representing the result (column => value): - # result.to_hash + # result.to_a # # => [{"id" => 1, "title" => "title_1", "body" => "body_1"}, # {"id" => 2, "title" => "title_2", "body" => "body_2"}, # ... @@ -65,9 +65,12 @@ module ActiveRecord end end - # Returns an array of hashes representing each row record. def to_hash - hash_rows + ActiveSupport::Deprecation.warn(<<-MSG.squish) + `ActiveRecord::Result#to_hash` has been renamed to `to_a`. + `to_hash` is deprecated and will be removed in Rails 6.1. + MSG + to_a end alias :map! :map @@ -83,6 +86,8 @@ module ActiveRecord hash_rows end + alias :to_a :to_ary + def [](idx) hash_rows[idx] end diff --git a/activerecord/test/cases/adapter_test.rb b/activerecord/test/cases/adapter_test.rb index a93e5e2b40..217ba22294 100644 --- a/activerecord/test/cases/adapter_test.rb +++ b/activerecord/test/cases/adapter_test.rb @@ -227,7 +227,7 @@ module ActiveRecord post = Post.create!(title: "foo", body: "bar") expected = @connection.select_all("SELECT * FROM posts WHERE id = #{post.id}") result = @connection.select_all("SELECT * FROM posts WHERE id = #{Arel::Nodes::BindParam.new(nil).to_sql}", nil, [[nil, post.id]]) - assert_equal expected.to_hash, result.to_hash + assert_equal expected.to_a, result.to_a end def test_insert_update_delete_with_legacy_binds diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb index 169ff96b94..43763dc715 100644 --- a/activerecord/test/cases/associations/belongs_to_associations_test.rb +++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb @@ -452,15 +452,39 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase end def test_belongs_to_counter_with_assigning_nil - post = Post.find(1) - comment = Comment.find(1) + topic = Topic.create!(title: "debate") + reply = Reply.create!(title: "blah!", content: "world around!", topic: topic) - assert_equal post.id, comment.post_id - assert_equal 2, Post.find(post.id).comments.size + assert_equal topic.id, reply.parent_id + assert_equal 1, topic.reload.replies.size - comment.post = nil + reply.topic = nil + reply.reload - assert_equal 1, Post.find(post.id).comments.size + assert_equal topic.id, reply.parent_id + assert_equal 1, topic.reload.replies.size + + reply.topic = nil + reply.save! + + assert_equal 0, topic.reload.replies.size + end + + def test_belongs_to_counter_with_assigning_new_object + topic = Topic.create!(title: "debate") + reply = Reply.create!(title: "blah!", content: "world around!", topic: topic) + + assert_equal topic.id, reply.parent_id + assert_equal 1, topic.reload.replies_count + + topic2 = reply.build_topic(title: "debate2") + reply.save! + + assert_not_equal topic.id, reply.parent_id + assert_equal topic2.id, reply.parent_id + + assert_equal 0, topic.reload.replies_count + assert_equal 1, topic2.reload.replies_count end def test_belongs_to_with_primary_key_counter @@ -485,11 +509,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal 0, debate2.reload.replies_count reply.topic_with_primary_key = debate2 + reply.save! assert_equal 0, debate.reload.replies_count assert_equal 1, debate2.reload.replies_count reply.topic_with_primary_key = nil + reply.save! assert_equal 0, debate.reload.replies_count assert_equal 0, debate2.reload.replies_count @@ -516,11 +542,13 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase assert_equal 1, Topic.find(topic2.id).replies.size reply1.topic = nil + reply1.save! assert_equal 0, Topic.find(topic1.id).replies.size assert_equal 0, Topic.find(topic2.id).replies.size reply1.topic = topic1 + reply1.save! assert_equal 1, Topic.find(topic1.id).replies.size assert_equal 0, Topic.find(topic2.id).replies.size @@ -594,6 +622,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase debate2.touch(time: time) reply.topic_with_primary_key = debate2 + reply.save! assert_operator debate.reload.updated_at, :>, time assert_operator debate2.reload.updated_at, :>, time @@ -772,6 +801,7 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase reply = Reply.create(title: "re: zoom", content: "speedy quick!") reply.topic = topic + reply.save! assert_equal 1, topic.reload[:replies_count] assert_equal 1, topic.replies.size diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb index 68fcafb682..825aee2423 100644 --- a/activerecord/test/cases/result_test.rb +++ b/activerecord/test/cases/result_test.rb @@ -21,12 +21,22 @@ module ActiveRecord assert_equal 3, result.length end - test "to_hash returns row_hashes" do + test "to_a returns row_hashes" do assert_equal [ { "col_1" => "row 1 col 1", "col_2" => "row 1 col 2" }, { "col_1" => "row 2 col 1", "col_2" => "row 2 col 2" }, { "col_1" => "row 3 col 1", "col_2" => "row 3 col 2" }, - ], result.to_hash + ], result.to_a + end + + test "to_hash (deprecated) returns row_hashes" do + assert_deprecated do + assert_equal [ + { "col_1" => "row 1 col 1", "col_2" => "row 1 col 2" }, + { "col_1" => "row 2 col 1", "col_2" => "row 2 col 2" }, + { "col_1" => "row 3 col 1", "col_2" => "row 3 col 2" }, + ], result.to_hash + end end test "first returns first row as a hash" do |