aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
authorMiklos Fazkeas <mfazekas@szemafor.com>2014-08-22 16:41:40 +0200
committerMiklos Fazekas <mfazekas@szemafor.com>2015-01-04 23:44:51 +0100
commitfb71fa695d214eb5aaa6f95440347e3a08f03b38 (patch)
treeb704f38b1c1a94d68b5623d2743933ba4fc3b8c7 /activerecord/lib
parent5868307b74161063b4476a792b4ad3571ec61817 (diff)
downloadrails-fb71fa695d214eb5aaa6f95440347e3a08f03b38.tar.gz
rails-fb71fa695d214eb5aaa6f95440347e3a08f03b38.tar.bz2
rails-fb71fa695d214eb5aaa6f95440347e3a08f03b38.zip
Fix potenital stack level too deep with autosave or validation
When associations checked for autosave have a cycle, and none of them is dirty, then changed_for_autosave? will be an infinite loop. We now remember if we're in the check and will short circuit the recursion.
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/autosave_association.rb15
1 files changed, 11 insertions, 4 deletions
diff --git a/activerecord/lib/active_record/autosave_association.rb b/activerecord/lib/active_record/autosave_association.rb
index fa6c5e9e8c..fcaaffb852 100644
--- a/activerecord/lib/active_record/autosave_association.rb
+++ b/activerecord/lib/active_record/autosave_association.rb
@@ -278,11 +278,18 @@ module ActiveRecord
# go through nested autosave associations that are loaded in memory (without loading
# any new ones), and return true if is changed for autosave
def nested_records_changed_for_autosave?
- self.class._reflections.values.any? do |reflection|
- if reflection.options[:autosave]
- association = association_instance_get(reflection.name)
- association && Array.wrap(association.target).any?(&:changed_for_autosave?)
+ @_nested_records_changed_for_autosave_already_called ||= false
+ return false if @_nested_records_changed_for_autosave_already_called
+ begin
+ @_nested_records_changed_for_autosave_already_called = true
+ self.class._reflections.values.any? do |reflection|
+ if reflection.options[:autosave]
+ association = association_instance_get(reflection.name)
+ association && Array.wrap(association.target).any?(&:changed_for_autosave?)
+ end
end
+ ensure
+ @_nested_records_changed_for_autosave_already_called = false
end
end