Deprecate locking of dirty records #25873
Conversation
r? @schneems (@rails-bot has picked a reviewer for you, use r? to override) |
Thank you for the pull request. What is the next step after this deprecation? When we remove the deprecation how the code will prevent this to happen again? |
I'd suggest to raise an exception, because that's easy to implement. But thinking about it, there is a way that would just prevent the record from being dirty in the first place: MyModel.where(attr: 42).first_with_lock! do |record|
# change record
record.save!
end On the other hand, this is more complicated, not as handy to use (you can't load the object, pass it to some other method, and lock it there), and might require major refactoring for the end users. So I'd still go with the exception. |
if persisted? | ||
if changed? | ||
ActiveSupport::Deprecation.warn(<<-MSG.squish) | ||
WARNING! Locking a record with unpersisted changes is deprecated. Use |
rafaelfranca
Jul 20, 2016
Member
No need to WARNING! here.
No need to WARNING! here.
rafaelfranca
Jul 20, 2016
Member
Locking a record with unpersisted changes is deprecated and will raise an exception in Rails 5.1. Use
Locking a record with unpersisted changes is deprecated and will raise an exception in Rails 5.1. Use
`save` to persist the changes, or `reload` to discard them explicitly. | ||
MSG | ||
end | ||
reload(:lock => lock) |
rafaelfranca
Jul 20, 2016
Member
Use Ruby 1.9 hash syntax here.
Use Ruby 1.9 hash syntax here.
@rafaelfranca I addressed your comments. |
@rafaelfranca Rebased. |
Could you add a CHANGELOG entry? |
if changed? | ||
ActiveSupport::Deprecation.warn(<<-MSG.squish) | ||
Locking a record with unpersisted changes is deprecated and will raise an | ||
exception in Rails 5.1. Use `save` to persist the changes, or `reload` to |
kamipo
Jan 18, 2017
Member
5.2?
5.2?
Added a changelog entry and changed the version in the deprecation notice to 5.2. |
@rafaelfranca Rebased again. |
@@ -59,7 +59,16 @@ module Pessimistic | |||
# or pass true for "FOR UPDATE" (the default, an exclusive row lock). Returns | |||
# the locked record. | |||
def lock!(lock = true) | |||
reload(lock: lock) if persisted? | |||
if persisted? | |||
if changed? |
rafaelfranca
Feb 7, 2017
Member
Sorry I forgot to ask before but can you add a test for this deprecation?
Sorry I forgot to ask before but can you add a test for this deprecation?
schuetzm
Feb 7, 2017
Author
Contributor
Done.
Done.
Deprecate locking of dirty records
lock!
andwith_lock
reload the record before doing the actual locking. If there were any unsaved changes, they will be discarded without any warning. IMO this behaviour is dangerous and error prone.See also #19743