🆕

Rails 7.1で個人的に気になったメソッドの変更点

2024/02/22に公開

はじめに

こんにちは、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::RelationArray#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を調べた結果をまとめたいと思います。

Social PLUS Tech Blog

Discussion