Rails
7.1.5.1 (December 10, 2024)¶ ↑
-
No changes.
Rails
7.1.5 (October 30, 2024)¶ ↑
-
Fix regression in
alias_attribute
to work with user defined methods.alias_attribute
would wrongly assume the attribute accessor was generated by Active Model.class Person include ActiveModel::AttributeMethods define_attribute_methods :name attr_accessor :name alias_attribute :full_name, :name end person.full_name # => NoMethodError: undefined method `attribute' for an instance of Person
Jean Boussier
Rails
7.1.4.2 (October 23, 2024)¶ ↑
-
No changes.
Rails
7.1.4.1 (October 15, 2024)¶ ↑
-
No changes.
Rails
7.1.4 (August 22, 2024)¶ ↑
-
No changes.
Rails
7.1.3.4 (June 04, 2024)¶ ↑
-
No changes.
Rails
7.1.3.3 (May 16, 2024)¶ ↑
-
No changes.
Rails
7.1.3.2 (February 21, 2024)¶ ↑
-
No changes.
Rails
7.1.3.1 (February 21, 2024)¶ ↑
-
No changes.
Rails
7.1.3 (January 16, 2024)¶ ↑
-
No changes.
Rails
7.1.2 (November 10, 2023)¶ ↑
-
Make
==(other)
method of AttributeSet safe.Dmitry Pogrebnoy
Rails
7.1.1 (October 11, 2023)¶ ↑
-
No changes.
Rails
7.1.0 (October 05, 2023)¶ ↑
-
No changes.
Rails
7.1.0.rc2 (October 01, 2023)¶ ↑
-
No changes.
Rails
7.1.0.rc1 (September 27, 2023)¶ ↑
-
Remove change in the typography of user facing error messages. For example, “can’t be blank” is again “can’t be blank”.
Rafael Mendonça França
Rails
7.1.0.beta1 (September 13, 2023)¶ ↑
-
Support composite identifiers in
to_key
to_key
avoids wrapping id value into anArray
if id already an arrayNikita Vasilevsky
-
Add
ActiveModel::Conversion.param_delimiter
to configure delimiter being used into_param
Nikita Vasilevsky
-
undefine_attribute_methods
undefines alias attribute methods along with attribute methods.Nikita Vasilevsky
-
Error.full_message now strips ":base" from the message.
zzak
-
Add a load hook for
ActiveModel::Model
(namedactive_model
) to match the load hook forActiveRecord::Base
and allow for overriding aspects of theActiveModel::Model
class.Lewis Buckley
-
Improve password length validation in
ActiveModel::SecurePassword
to consider byte size for BCrypt compatibility.The previous password length validation only considered the character count, which may not accurately reflect the 72-byte size limit imposed by BCrypt. This change updates the validation to consider both character count and byte size while keeping the character length validation in place.
user = User.new(password: "a" * 73) # 73 characters user.valid? # => false user.errors[:password] # => ["is too long"] user = User.new(password: "あ" * 25) # 25 characters, 75 bytes user.valid? # => false user.errors[:password] # => ["is too long"]
ChatGPT, Guillermo Iguaran
-
has_secure_password
now generates an#{attribute}_salt
method that returns the salt used to compute the password digest. The salt will change whenever the password is changed, so it can be used to create single-use password reset tokens withgenerates_token_for
:class User < ActiveRecord::Base has_secure_password generates_token_for :password_reset, expires_in: 15.minutes do password_salt&.last(10) end end
Lázaro Nixon
-
Improve typography of user facing error messages. In English contractions, the Unicode APOSTROPHE (
U+0027
) is now RIGHT SINGLE QUOTATION MARK (U+2019
). For example, “can’t be blank” is now “can’t be blank”.Jon Dufresne
-
Add class to
ActiveModel::MissingAttributeError
error message.Show which class is missing the attribute in the error message:
user = User.first user.pets.select(:id).first.user_id # => ActiveModel::MissingAttributeError: missing attribute 'user_id' for Pet
Petrik de Heus
-
Raise
NoMethodError
inActiveModel::Type::Value#as_json
to avoid unpredictable results.Vasiliy Ermolovich
-
Custom attribute types that inherit from Active Model built-in types and do not override the
serialize
method will now benefit from an optimization when serializing attribute values for the database.For example, with a custom type like the following:
class DowncasedString < ActiveModel::Type::String def cast(value) super&.downcase end end ActiveRecord::Type.register(:downcased_string, DowncasedString) class User < ActiveRecord::Base attribute :email, :downcased_string end user = User.new(email: "FooBar@example.com")
Serializing the
email
attribute for the database will be roughly twice as fast. More expensivecast
operations will likely see greater improvements.Jonathan Hefner
-
has_secure_password
now supports password challenges via apassword_challenge
accessor and validation.A password challenge is a safeguard to verify that the current user is actually the password owner. It can be used when changing sensitive model fields, such as the password itself. It is different than a password confirmation, which is used to prevent password typos.
When
password_challenge
is set, the validation checks that the value's digest matches the currently persistedpassword_digest
(i.e.password_digest_was
).This allows a password challenge to be done as part of a typical
update
call, just like a password confirmation. It also allows a password challenge error to be handled in the same way as other validation errors.For example, in the controller, instead of:
password_params = params.require(:password).permit( :password_challenge, :password, :password_confirmation, ) password_challenge = password_params.delete(:password_challenge) @password_challenge_failed = !current_user.authenticate(password_challenge) if !@password_challenge_failed && current_user.update(password_params) # ... end
You can now write:
password_params = params.require(:password).permit( :password_challenge, :password, :password_confirmation, ).with_defaults(password_challenge: "") if current_user.update(password_params) # ... end
And, in the view, instead of checking
@password_challenge_failed
, you can render an error for thepassword_challenge
field just as you would for other form fields, including utilizingconfig.action_view.field_error_proc
.Jonathan Hefner
-
Support infinite ranges for
LengthValidator
s:in
/:within
optionsvalidates_length_of :first_name, in: ..30
fatkodima
-
Add support for beginless ranges to inclusivity/exclusivity validators:
validates_inclusion_of :birth_date, in: -> { (..Date.today) }
validates_exclusion_of :birth_date, in: -> { (..Date.today) }
Bo Jeanes
-
Make validators accept lambdas without record argument
# Before validates_comparison_of :birth_date, less_than_or_equal_to: ->(_record) { Date.today } # After validates_comparison_of :birth_date, less_than_or_equal_to: -> { Date.today }
fatkodima
-
Fix casting long strings to
Date
,Time
orDateTime
fatkodima
-
Use different cache namespace for proxy calls
Models can currently have different attribute bodies for the same method names, leading to conflicts. Adding a new namespace
:active_model_proxy
fixes the issue.Chris Salzberg
Please check 7-0-stable for previous changes.