Skip to content

Commit c8caf6d

Browse files
committed
[Fix rails#49874] has_secure_token calls the setter method on initialize
Follow-up to rails#49146 The original behavior of `has_secure_token` was to use the `send("#{attribute}=", some_value)` method so that the setter method, if defined, was called. PR rails#49146 replaced the `send` method with `write_attribute` which doesn't call the setter method and breaks existing applications.
1 parent 6908a66 commit c8caf6d

File tree

3 files changed

+23
-1
lines changed

3 files changed

+23
-1
lines changed

activerecord/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
* Fix `has_secure_token` calls the setter method on initialize.
2+
3+
*Abeid Ahmed*
4+
15
* When using a `DATABASE_URL`, allow for a configuration to map the protocol in the URL to a specific database
26
adapter. This allows decoupling the adapter the application chooses to use from the database connection details
37
set in the deployment environment.

activerecord/lib/active_record/secure_token.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def has_secure_token(attribute = :token, length: MINIMUM_TOKEN_LENGTH, on: Activ
5353
define_method("regenerate_#{attribute}") { update! attribute => self.class.generate_unique_secure_token(length: length) }
5454
set_callback on, on == :initialize ? :after : :before do
5555
if new_record? && !query_attribute(attribute)
56-
write_attribute(attribute, self.class.generate_unique_secure_token(length: length))
56+
send("#{attribute}=", self.class.generate_unique_secure_token(length: length))
5757
end
5858
end
5959
end

activerecord/test/cases/secure_token_test.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,4 +98,22 @@ def test_token_on_callback
9898

9999
assert_predicate user.token, :present?
100100
end
101+
102+
def test_token_calls_the_setter_method
103+
model = Class.new(ActiveRecord::Base) do
104+
self.table_name = "users"
105+
has_secure_token on: :initialize
106+
107+
attr_accessor :modified_token
108+
109+
def token=(value)
110+
super
111+
self.modified_token = "#{value}_modified"
112+
end
113+
end
114+
115+
user = model.new
116+
117+
assert_equal "#{user.token}_modified", user.modified_token
118+
end
101119
end

0 commit comments

Comments
 (0)