mirror of https://github.com/rails/rails
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 @@ module ActiveRecord
|
|||
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 @@ class SecureTokenTest < ActiveRecord::TestCase
|
|||
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