aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorJames Coleman <jtc331@gmail.com>2016-02-05 10:16:15 -0500
committerJames Coleman <jtc331@gmail.com>2016-08-26 11:40:38 -0400
commita94fe2971b24d2a7827e205e7898e1b22771ed72 (patch)
tree9a6ff88242201d4fb55e29ae97146a921204bf25 /activerecord
parentf394f3ba763adbd073685a4a3f53b2a3ad71381a (diff)
downloadrails-a94fe2971b24d2a7827e205e7898e1b22771ed72.tar.gz
rails-a94fe2971b24d2a7827e205e7898e1b22771ed72.tar.bz2
rails-a94fe2971b24d2a7827e205e7898e1b22771ed72.zip
Don't unnecessarily load a belongs_to when saving.
Previously, if the the association was previously loaded and then the foreign key changed by itself, a #save call would trigger a load of the new associated record during autosave. This is unnecessary and the autosave code (in that case) didn't use the loaded record anyways.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/CHANGELOG.md5
-rw-r--r--activerecord/lib/active_record/autosave_association.rb4
-rw-r--r--activerecord/test/cases/associations/belongs_to_associations_test.rb6
3 files changed, 14 insertions, 1 deletions
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index 4aa1853bde..7838fe7167 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,8 @@
+* Remove unnecessarily association load when a `belongs_to` association has already been
+ loaded then the foreign key is changed directly and the record saved.
+
+ *James Coleman*
+
* Remove standardized column types/arguments spaces in schema dump.
*Tim Petricola*
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index 6e6620aad5..db84876b0a 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -457,7 +457,9 @@ module ActiveRecord
# In addition, it will destroy the association if it was marked for destruction.
def save_belongs_to_association(reflection)
association = association_instance_get(reflection.name)
- record = association && association.load_target
+ return unless association && association.loaded? && !association.stale_target?
+
+ record = association.load_target
if record && !record.destroyed?
autosave = reflection.options[:autosave]
diff --git a/activerecord/test/cases/associations/belongs_to_associations_test.rb b/activerecord/test/cases/associations/belongs_to_associations_test.rb
index 3f42cb9b9d..2418346d1b 100644
--- a/activerecord/test/cases/associations/belongs_to_associations_test.rb
+++ b/activerecord/test/cases/associations/belongs_to_associations_test.rb
@@ -626,6 +626,12 @@ class BelongsToAssociationsTest < ActiveRecord::TestCase
assert_queries(0) { tagging.super_tag }
end
+ def test_dont_find_target_when_saving_foreign_key_after_stale_association_loaded
+ client = Client.create!(name: "Test client", firm_with_basic_id: Firm.find(1))
+ client.firm_id = Firm.create!(name: "Test firm").id
+ assert_queries(1) { client.save! }
+ end
+
def test_field_name_same_as_foreign_key
computer = Computer.find(1)
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '