Ensure suppressor runs before validations

I ran into an issue where validations on a suppressed record were
causing validation errors to be thrown on a record that was never going
to be saved.

There isn't a reason to run the validations on a record that doesn't
matter.

This change moves the suppressor up the chain to be run on the `save` or
`save!` in the validations rather than in persistence. The issue with
running it when we hit persistence is that the validations are run
first, then we hit persistance, and then we hit the suppressor. The
suppressor comes first.

The change to the test was required since I added the
`validates_presence_of` validations. Adding this alone was enough to
demonstrate the issue. I added a new test to demonstrate the new
behavior is explict.
This commit is contained in:
eileencodes 2016-02-24 13:45:36 -05:00
parent a5776ed2b2
commit 73f8c16601
4 changed files with 25 additions and 2 deletions

@ -1,3 +1,10 @@
* Ensure that the Suppressor runs before validations.
This moves the suppressor up to be run before validations rather than after
validations. There's no reason to validate a record you aren't planning on saving.
*Eileen M. Uchitelle*
## Rails 5.0.0.beta3 (February 24, 2016) ##
* Ensure that mutations of the array returned from `ActiveRecord::Relation#to_a`

@ -37,7 +37,11 @@ def suppress(&block)
end
end
def create_or_update(*args) # :nodoc:
def save(*) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super
end
def save!(*) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super
end
end

@ -46,7 +46,18 @@ def test_resumes_saving_after_suppression_complete
Notification.suppress { UserWithNotification.create! }
assert_difference -> { Notification.count } do
Notification.create!
Notification.create!(message: "New Comment")
end
end
def test_suppresses_validations_on_create
assert_no_difference -> { Notification.count } do
Notification.suppress do
User.create
User.create!
User.new.save
User.new.save!
end
end
end
end

@ -1,2 +1,3 @@
class Notification < ActiveRecord::Base
validates_presence_of :message
end