-
Notifications
You must be signed in to change notification settings - Fork 21.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add ActiveRecord::Base.suppress
to allow save events to be suppressed within a specified block.
#18910
Conversation
def test_suppresses_creation_of_related_record_on_after_create_callback | ||
count = Notification.count | ||
Notification.suppress { UserWithNotification.create! } | ||
assert_equal count, Notification.count |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should assert that other models used in the suppress block -- in this case, User -- are unaffected:
assert_difference -> { User.count } do
assert_no_difference -> { Notification.count } do
Notification.suppress { UserWithNotification.create! }
end
end
Thanks for the feedback, @georgeclaghorn and @kaspth. |
@@ -0,0 +1,57 @@ | |||
module ActiveRecord | |||
# ActiveRecord::Suppressor allows save events to be suppressed within a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still think callbacks
is clearer than events
here 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's more along the lines of what I originally had and again included, but lost when I moved the comment up to the class level. There's a stray line break in there too, so I'll fix once there's feedback on this commit.
If you want you can blame the original author here: #18847. 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, let's give him a pass. But just this once 😉
Left some notes, otherwise this looks good. Thanks for working on it 😄 Just so you know, it doesn't seem like GitHub supports "closes #x" in the Pull Request title: https://github.com/blog/1506-closing-issues-via-pull-requests. But the issue will close when this is merged, because you've put the issue number in your commit message. |
ActiveRecord::Base.suppress
to allow save events to be suppressed within a specified block. Closes #18847.ActiveRecord::Base.suppress
to allow save events to be suppressed within a specified block.
Does |
@@ -1,3 +1,34 @@ | |||
* Add `ActiveRecord::Base.suppress` to allow save callbacks to be suppressed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It prevents saves, not save callbacks. It is useful to prevent undesirable saves happening in callbacks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, I suggested this. My mental model was off on what this actually does.
I don't really agree with this change. First, I don't think that there's a legitimate use case for this, and second, I don't think this is the correct solution to this problem. I have rarely ever seen a case where I've added a callback that involves saving another record and then for some reason I don't want that save to occur. I can see this happening in tests, but that is easily solved by stubbing the method that performs the save ( Even if that were not the case, I think that the usage is weird. As a reader of this code, it seems like the context around the use of Anyway... that's a bit of a moot point, because honestly I think both problems can be solved by making a separate class that encapsulates creating a comment and also creating a notification. Is it one more class? Sure, but you don't have to disable anything, and the intention is perfectly clear to other people reading the code. |
@mcmire please see the original issue #18847 for a use case and justification. @perceptec can you add "Fixes #18847" to the description, so others will have an easier time evaluating this? 😄 |
Looking good @perceptec! Did @kaspth or @georgeclaghorn have any other comments, or are we good to merge? @mcmire What @kaspth said. Use case is explained in the original issue. |
end | ||
end | ||
|
||
Closes #18847. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to point to the issue at the changelog since it is a new feature
Looks good to me! |
@mcmire The general principle I apply for this design is "the exception must carry the weight of its own work". If you create a new CreateCommentWithNotifications object, you're pushing the weight of the work onto the default case. That's not proportional in my book. |
Once @georgeclaghorn's and @rafaelfranca's concerns are addressed then 👍 Oh, and we'll need a rebase @perceptec 😄 |
This one's been slippery to define. "save callbacks" was intended more in a compound sense (if a bit of a cop-out). Will this work? (Since there's already been discussion/confusion around the intended functionality.)
No matter what we come up with for a definition, I think the code itself will be more illustrative... |
It's not necessary to mention callbacks at all. |
Maybe |
@georgeclaghorn True, is everybody okay with @rafaelfranca's edit? |
What George said. Let’s just focus on suppress = no saving of records.
|
👍 |
belongs_to :commentable, polymorphic: true | ||
after_create -> { Notification.create! comment: self, | ||
recipients: commentable.recipients } | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent code examples in this file by an extra four spaces.
Add `ActiveRecord::Base.suppress` to allow save events to be suppressed within a specified block.
Boom! Well done @perceptec 😄 Kasper
|
Great job 👏 |
(Removed a disparaging comment about the feature that was thoughtlessly posted on the implementation work done here. Please contribute to discussion on the original issue #18847.) |
Fixes #18847.