Generate secure token only once regardless of on: :initialize
or on: :create
Follow-up to #47420. Whereas the original behavior (`on: :create`) is invoked only once before a record is persisted, the new behavior (`on: :initialize`) is invoked not only new record but also persisted records. It should be invoked only once for new record consistently.
This commit is contained in:
parent
2fbb25b771
commit
2df70ddb96
@ -52,7 +52,9 @@ def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: Activ
|
||||
require "active_support/core_ext/securerandom"
|
||||
define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token(length: length) }
|
||||
set_callback on, on == :initialize ? :after : :before do
|
||||
send("#{attribute}=", self.class.generate_unique_secure_token(length: length)) if has_attribute?(attribute) && !send("#{attribute}?")
|
||||
if new_record? && !query_attribute(attribute)
|
||||
write_attribute(attribute, self.class.generate_unique_secure_token(length: length))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -25,6 +25,22 @@ def test_generating_token_on_initialize_does_not_affect_reading_from_the_column
|
||||
assert_equal token, User.find(@user.id).token
|
||||
end
|
||||
|
||||
def test_generating_token_on_initialize_happens_only_once
|
||||
model = Class.new(ActiveRecord::Base) do
|
||||
self.table_name = "users"
|
||||
has_secure_token on: :initialize
|
||||
end
|
||||
|
||||
token = " "
|
||||
|
||||
user = model.new
|
||||
user.update!(token: token)
|
||||
|
||||
assert_equal token, user.token
|
||||
assert_equal token, user.reload.token
|
||||
assert_equal token, model.find(user.id).token
|
||||
end
|
||||
|
||||
def test_generating_token_on_initialize_is_skipped_if_column_was_not_selected
|
||||
model = Class.new(ActiveRecord::Base) do
|
||||
self.table_name = "users"
|
||||
|
Loading…
Reference in New Issue
Block a user