Skip to content

Commit d44e786

Browse files
Add CHANGELOG entry for rails#44189 [ci-skip]
1 parent e240daa commit d44e786

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

activerecord/CHANGELOG.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,36 @@
1+
* Add new `ActiveRecord::Base::generates_token_for` API.
2+
3+
Currently, `signed_id` fulfills the role of generating tokens for e.g.
4+
resetting a password. However, signed IDs cannot reflect record state, so
5+
if a token is intended to be single-use, it must be tracked in a database at
6+
least until it expires.
7+
8+
With `generates_token_for`, a token can embed data from a record. When
9+
using the token to fetch the record, the data from the token and the data
10+
from the record will be compared. If the two do not match, the token will
11+
be treated as invalid, the same as if it had expired. For example:
12+
13+
```ruby
14+
class User < ActiveRecord::Base
15+
has_secure_password
16+
17+
generates_token_for :password_reset, expires_in: 15.minutes do
18+
# A password's BCrypt salt changes when the password is updated.
19+
# By embedding (part of) the salt in a token, the token will
20+
# expire when the password is updated.
21+
BCrypt::Password.new(password_digest).salt[-10..]
22+
end
23+
end
24+
25+
user = User.first
26+
token = user.generate_token_for(:password_reset)
27+
28+
User.find_by_token_for(:password_reset, token) # => user
29+
30+
user.update!(password: "new password")
31+
User.find_by_token_for(:password_reset, token) # => nil
32+
```
33+
134
* Optimize Active Record batching for whole table iterations.
235

336
Previously, `in_batches` got all the ids and constructed an `IN`-based query for each batch.

0 commit comments

Comments
 (0)