-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
MONGOID-5658 Fix callbacks for embedded #5727
MONGOID-5658 Fix callbacks for embedded #5727
Conversation
@@ -137,6 +137,16 @@ module Config | |||
# See https://jira.mongodb.org/browse/MONGOID-5542 | |||
option :prevent_multiple_calls_of_embedded_callbacks, default: true | |||
|
|||
# When this flag is true, callbacks for embedded documents will not be | |||
# called. This is the default in 9.0. |
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 feel like the name of the option might be backwards, if this is the case. I would expect around_callbacks_for_embeds = true
to mean that around callbacks are invoked. If we want a true value to mean they are not invoked, perhaps the option should be called something like omit_around_callbacks_for_embeds
?
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.
Updated, thank you!
@@ -149,6 +149,14 @@ def run_callbacks(kind, with_children: true, skip_if: nil, &block) | |||
# | |||
# @api private | |||
def _mongoid_run_child_callbacks(kind, children: nil, &block) | |||
if Mongoid::Config.around_callbacks_for_embeds |
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.
The logic here seems to contradict the documentation for the around_callbacks_for_embeds
option. Maybe the documentation just has the logic backwards?
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 are right, thank you. Adjusted the docs.
@@ -162,6 +170,46 @@ def _mongoid_run_child_callbacks(kind, children: nil, &block) | |||
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.
(GitHub won't let me leave a comment on a line of code that's not actually part of the PR, so I'm leaving it here)
A few lines above this, _mongoid_run_child_callbacks
is invoked, which is fine. However, since we already know that around callbacks for embeds are enabled, we might as well just invoke _mongoid_run_child_callbacks_with_around
, and avoid adding an extra call to the stack.
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.
Good catch, thank you. Fixed.
lib/mongoid/interceptable.rb
Outdated
@@ -162,6 +170,46 @@ def _mongoid_run_child_callbacks(kind, children: nil, &block) | |||
end | |||
end | |||
|
|||
def _mondoid_run_child_before_callbacks(kind, children: [], callback_list: []) |
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.
mondoid --> mongoid
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.
Fixed, thank you. Mondoid sounds kind of nice, though...
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.
Mondoid does sound kind of nice
lib/mongoid/interceptable.rb
Outdated
callback_list | ||
end | ||
|
||
def _mondoid_run_child_after_callbacks(callback_list: []) |
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.
mondoid --> mongoid
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.
Fixed, thanks.
This is a band-aid for MONGOID-5658
The existing implementation of callbacks guarantees a sane order of execution; however, it causes stack overflow if there are many embeddeds (even in a flat structure). To fix this issue we suggest ignoring around callbacks for embedded documents. This allows us to patch the existing implementation of the callbacks and keep the proper order of callbacks.
If something still needs to be done around a database operation for an embedded document, it can be done in corresponding callback of the parent document.
We should discuss a necessity of callbacks for embedded documents in general. If we still feel that we should keep this functionality, the callbacks implementation in general should be revised.