Skip to content

Commit cf10924

Browse files
authored
Merge pull request rails#49146 from kamipo/generating_token_only_once
Generate secure token only once regardless of `on: :initialize` or `on: :create`
2 parents 11257c8 + 2df70dd commit cf10924

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

activerecord/lib/active_record/secure_token.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,9 @@ def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: Activ
5252
require "active_support/core_ext/securerandom"
5353
define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token(length: length) }
5454
set_callback on, on == :initialize ? :after : :before do
55-
send("#{attribute}=", self.class.generate_unique_secure_token(length: length)) if has_attribute?(attribute) && !send("#{attribute}?")
55+
if new_record? && !query_attribute(attribute)
56+
write_attribute(attribute, self.class.generate_unique_secure_token(length: length))
57+
end
5658
end
5759
end
5860

activerecord/test/cases/secure_token_test.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ def test_generating_token_on_initialize_does_not_affect_reading_from_the_column
3131
assert_equal token, model.find(user.id).token
3232
end
3333

34+
def test_generating_token_on_initialize_happens_only_once
35+
model = Class.new(ActiveRecord::Base) do
36+
self.table_name = "users"
37+
has_secure_token on: :initialize
38+
end
39+
40+
token = " "
41+
42+
user = model.new
43+
user.update!(token: token)
44+
45+
assert_equal token, user.token
46+
assert_equal token, user.reload.token
47+
assert_equal token, model.find(user.id).token
48+
end
49+
3450
def test_generating_token_on_initialize_is_skipped_if_column_was_not_selected
3551
model = Class.new(ActiveRecord::Base) do
3652
self.table_name = "users"

0 commit comments

Comments
 (0)