🆕
Rails 7.1で個人的に気になった変更点
はじめに
こんにちは、kmkntです。
本記事では、Rails 7.1の変更点について、CHANGELOGを読んで個人的に気になったものをまとめました。
そのバージョンで目玉となるような新しい機能の追加など、大きな変更点はネット上の様々な記事で紹介されていますが、細かいメソッド周りの変更点はあまり触れられていないので、自身のキャッチアップも兼ねて整理したいというのが趣旨になります。参考になれば幸いです。
以降、7.1.3のActive Support、Active Record、Active ModelのCHANGELOGおよびRuby on Rails Guidesを参照しています。
(7.1.0から7.1.3までの変更点を含んでいます)
Active Support
-
Object#with
を使うことでブロックの中でのみ有効な属性を設定できるようになりました。
client.timeout # => 5
client.with(timeout: 1) do
client.timeout # => 1
end
client.timeout # => 5
-
TimeHelpers#travel_to
の中でTime.newをスタブにできるようになりました。
travel_to Time.new(2004, 11, 24) do
# Inside the `travel_to` block `Time.new` is stubbed
assert_equal 2004, Time.new.year
end
-
Object#in?
がopen rangesをサポートしました。
assert Date.today.in?(..Date.tomorrow)
assert_not Date.today.in?(Date.tomorrow..)
-
Rails.env.local?
がRails.env.development? || Rails.env.test?
のショートハンドとして追加されました。 -
String#downcase_first
が追加されました。
"If I had read Alice in Wonderland".downcase_first # => "if I had read Alice in Wonderland"
- date/timeに
quarter
が追加されました。
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
d.quarter # => 2
Active Record
- カラムが存在しないattributesでもenumが使える機能が再度有効になりました(ただし、attributesは事前に型を指定して定義しておく必要があります)。
class Post < ActiveRecord::Base
attribute :topic, :string
enum topic: %i[science tech engineering math]
end
- enumにvalidation optionが追加されました。
class Contract < ApplicationRecord
enum :status, %w[in_progress completed], validate: true
end
Contract.new(status: "unknown").valid? # => false
Contract.new(status: nil).valid? # => false
Contract.new(status: "completed").valid? # => true
class Contract < ApplicationRecord
enum :status, %w[in_progress completed], validate: { allow_nil: true }
end
Contract.new(status: "unknown").valid? # => false
Contract.new(status: nil).valid? # => true
Contract.new(status: "completed").valid? # => true
-
ActiveRecord::Relation
がArray#intersect?
をサポートしました(ただし、Ruby 3.1以上)。 -
#regroup
が.unscope(:group).group(fields)
のショートハンドとして追加されました。
Post.group(:title).regroup(:author)
# SELECT `posts`.`*` FROM `posts` GROUP BY `posts`.`author`
-
QueryMethods#in_order_of
が文字列のカラム名でorderできるようになりました。
Post.in_order_of("id", [4,2,3,1]).to_a
Post.joins(:author).in_order_of("authors.name", ["Bob", "Anna", "John"]).to_a
-
ActiveRecord::QueryMethods#select
がHashを受け取れるようになりました。
Post.joins(:comments).select(posts: [:id, :title, :created_at], comments: [:id, :body, :author_id])
#=> "SELECT \"posts\".\"id\", \"posts\".\"title\", \"posts\".\"created_at\", \"comments\".\"id\", \"comments\".\"body\", \"comments\".\"author_id\"
# FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
Post.joins(:comments).select(posts: { id: :post_id, title: :post_title }, comments: { id: :comment_id, body: :comment_body })
#=> "SELECT posts.id as post_id, posts.title as post_title, comments.id as comment_id, comments.body as comment_body
# FROM \"posts\" INNER JOIN \"comments\" ON \"comments\".\"post_id\" = \"posts\".\"id\""
Active Model
- LengthValidatorsの:in/:within optionsがinfinite rangesをサポートしました。
validates_length_of :first_name, in: ..30
- inclusivity/exclusivity validatorsがbeginless rangesをサポートしました。
validates_inclusion_of :birth_date, in: -> { (..Date.today) }
validates_exclusion_of :birth_date, in: -> { (..Date.today) }
最後に
Railsのバージョンアップで便利なメソッドやオプションが追加されているにも関わらず、CHANGELOGにしか記載がないため知らないままになってしまうというのが割と起こりがちなので、記事にまとめてみました。
Rails 7.2がリリースされたら、またCHANGELOGを調べた結果をまとめたいと思います。
Discussion