rubyonrails.org에서 더 보기:

이 파일을 GITHUB에서 읽지 마세요. 가이드는 https://guides.rubyonrails.org 에서 제공됩니다.

Ruby on Rails 7.1 릴리스 노트

Rails 7.1의 주요 내용:

  • 새로운 Rails 애플리케이션을 위한 Dockerfile 생성
  • ActiveRecord::Base.normalizes 추가
  • ActiveRecord::Base.generates_token_for 추가
  • 여러 job을 한 번에 큐에 추가하기 위한 perform_all_later 추가
  • Composite primary keys
  • Trilogy를 위한 adapter 도입
  • ActiveSupport::MessagePack 추가
  • 향상된 Autoloading을 위한 config.autoload_libconfig.autoload_lib_once 도입
  • 일반적인 async 쿼리를 위한 Active Record API
  • 템플릿에서 엄격한 locals 설정 허용
  • Rails.application.deprecators 추가
  • JSON response.parsed_body에 대한 패턴 매칭 지원
  • Nokogiri로 HTML을 파싱하기 위한 response.parsed_body 확장
  • ActionView::TestCase.register_parser 도입

이 릴리스 노트는 주요 변경 사항만을 다룹니다. 다양한 버그 수정과 변경 사항에 대해 알아보려면 changelog를 참조하거나 GitHub의 Rails 메인 저장소에 있는 커밋 목록을 확인하세요.

1 Rails 7.1로 업그레이드하기

기존 애플리케이션을 업그레이드하는 경우, 진행하기 전에 충분한 테스트 커버리지를 확보하는 것이 좋습니다. 아직 Rails 7.0으로 업그레이드하지 않았다면 먼저 7.0으로 업그레이드하고, Rails 7.1로 업그레이드를 시도하기 전에 애플리케이션이 예상대로 작동하는지 확인해야 합니다. 업그레이드 시 주의해야 할 사항 목록은 Ruby on Rails 업그레이드하기 가이드에서 확인할 수 있습니다.

2 주요 기능

2.1 새로운 Rails 애플리케이션을 위한 Dockerfile 생성

새로운 Rails 애플리케이션에 대한 기본 Docker 지원입니다. 새로운 애플리케이션을 생성할 때, Rails는 이제 애플리케이션에 Docker 관련 파일들을 포함합니다.

이러한 파일들은 Docker를 사용하여 프로덕션 환경에서 Rails 애플리케이션을 배포하기 위한 기초 설정으로 제공됩니다. 이 파일들은 개발 목적으로 사용되지 않는다는 점을 유의해야 합니다.

다음은 이러한 Docker 파일들을 사용하여 Rails 앱을 빌드하고 실행하는 간단한 예시입니다:

$ docker build -t app .
$ docker volume create app-storage
$ docker run --rm -it -v app-storage:/rails/storage -p 3000:3000 --env RAILS_MASTER_KEY=<config-master-key 값> app

이 Docker 이미지에서도 console이나 runner를 실행할 수 있습니다:

$ docker run --rm -it -v app-storage:/rails/storage --env RAILS_MASTER_KEY=<config-master-key를 입력하세요> app console

멀티 플랫폼 이미지(예: AMD나 Intel 환경에서 구동할 Apple Silicon용)를 생성하고 Docker Hub에 푸시하려는 경우, 다음 단계를 따르세요:

$ docker login -u <당신의-사용자명>
$ docker buildx create --use
$ docker buildx build --push --platform=linux/amd64,linux/arm64 -t <당신의-사용자명/이미지-이름> .

이 개선사항은 배포 프로세스를 단순화하여, production 환경에서 Rails application을 가동하고 실행하기 위한 편리한 시작점을 제공합니다.

2.2 ActiveRecord::Base.normalizes 추가

ActiveRecord::Base.normalizes는 attribute 정규화를 선언합니다. 이 정규화는 attribute가 할당되거나 업데이트될 때 적용되며, 정규화된 값은 데이터베이스에 저장됩니다. 또한 정규화는 query method의 해당 keyword argument에도 적용되어, 정규화되지 않은 값을 사용해서도 record를 조회할 수 있습니다.

예시:

class User < ActiveRecord::Base
  normalizes :email, with: -> email { email.strip.downcase }
  normalizes :phone, with: -> phone { phone.delete("^0-9").delete_prefix("1") }
end

user = User.create(email: " CRUISE-CONTROL@EXAMPLE.COM\n") 
user.email                  # => "cruise-control@example.com"

user = User.find_by(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")
user.email                  # => "cruise-control@example.com"
user.email_before_type_cast # => "cruise-control@example.com" 

# 정규화된 값으로 데이터를 찾습니다
User.where(email: "\tCRUISE-CONTROL@EXAMPLE.COM ").count         # => 1
User.where(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]).count # => 0

User.exists?(email: "\tCRUISE-CONTROL@EXAMPLE.COM ")         # => true
User.exists?(["email = ?", "\tCRUISE-CONTROL@EXAMPLE.COM "]) # => false

# 필드의 정규화 규칙을 직접 적용해볼 수 있습니다
User.normalize_value_for(:phone, "+1 (555) 867-5309") # => "5558675309"

2.3 ActiveRecord::Base.generates_token_for 추가

ActiveRecord::Base.generates_token_for는 특정 목적을 위한 토큰 생성을 정의합니다. 생성된 토큰은 만료될 수 있으며 레코드 데이터를 포함할 수도 있습니다. 토큰을 사용하여 레코드를 가져올 때, 토큰의 데이터와 레코드의 현재 데이터를 비교합니다. 두 데이터가 일치하지 않으면, 토큰은 만료된 것과 동일하게 유효하지 않은 것으로 처리됩니다.

다음은 일회용 비밀번호 재설정 토큰을 구현하는 예시입니다:

class User < ActiveRecord::Base
  has_secure_password

  generates_token_for :password_reset, expires_in: 15.minutes do
    # `password_salt`(`has_secure_password`에 의해 정의됨)은 비밀번호의 salt를 반환합니다.
    # salt는 비밀번호가 변경될 때 변경되므로, 비밀번호가 변경되면 토큰도 만료됩니다.
    password_salt&.last(10)
  end
end

user = User.first
token = user.generate_token_for(:password_reset)

User.find_by_token_for(:password_reset, token) # => user

user.update!(password: "new password")
User.find_by_token_for(:password_reset, token) # => nil

2.4 한 번에 여러 job을 대기열에 추가하는 perform_all_later 추가

Active Job의 perform_all_later 메서드는 여러 job을 동시에 대기열에 넣는 프로세스를 간소화하도록 설계되었습니다. 이 강력한 추가 기능을 사용하면 callback을 트리거하지 않고도 효율적으로 job을 대기열에 넣을 수 있습니다. 이는 특히 한 번에 여러 job을 대기열에 넣어야 할 때 유용하며, queue datastore에 대한 여러 번의 왕복 오버헤드를 줄일 수 있습니다.

다음과 같이 perform_all_later를 활용할 수 있습니다:

# 개별 job 엔큐하기
ActiveJob.perform_all_later(MyJob.new("hello", 42), MyJob.new("world", 0))

# job 배열 엔큐하기 
user_jobs = User.pluck(:id).map { |id| UserJob.new(user_id: id) }
ActiveJob.perform_all_later(user_jobs)

perform_all_later를 활용하면 작업 큐 처리 과정을 최적화할 수 있으며, 특히 대량의 job을 다룰 때 향상된 효율성의 이점을 얻을 수 있습니다. Sidekiq adapter와 같이 새로운 enqueue_all 메서드를 지원하는 queue adapter의 경우, push_bulk를 사용하여 큐 처리 과정이 더욱 최적화된다는 점을 주목할 만합니다.

이 새로운 메서드는 enqueue_all.active_job이라는 별도의 이벤트를 도입하며, 기존의 enqueue.active_job 이벤트를 사용하지 않는다는 점에 유의하시기 바랍니다. 이를 통해 대량 큐 처리 과정의 정확한 추적과 보고가 보장됩니다.

2.5 Composite primary keys

이제 데이터베이스와 애플리케이션 레벨 모두에서 Composite primary keys가 지원됩니다. Rails는 스키마에서 직접 이러한 키들을 도출할 수 있습니다. 이 기능은 특히 단일 컬럼으로는 레코드를 고유하게 식별하기 불충분한 다대다 관계와 기타 복잡한 데이터 모델에서 유용합니다.

Active Record의 쿼리 메서드(예: #reload, #update, #delete)에 의해 생성되는 SQL은 composite primary key의 모든 부분을 포함하게 됩니다. #first#last 같은 메서드들은 ORDER BY 구문에서 전체 composite primary key를 사용할 것입니다.

query_constraints 매크로는 데이터베이스 스키마를 수정하지 않고도 동일한 동작을 달성할 수 있는 "가상 primary key"로 사용될 수 있습니다. 예시:

class TravelRoute < ActiveRecord::Base
  query_constraints :origin, :destination
end

TravelRoute model은 :origin:destination attribute가 조합되어 특정 record를 query할 때 함께 사용될 수 있다는 것을 명시적으로 선언합니다.

유사하게 associations도 query_constraints: 옵션을 받습니다. 이 옵션은 composite foreign key로 작동하며, 연관된 레코드에 접근하기 위해 사용되는 컬럼 목록을 구성합니다.

예시:

class TravelRouteReview < ActiveRecord::Base
  belongs_to :travel_route, query_constraints: [:travel_route_origin, :travel_route_destination]
  # travel_route_origin과 travel_route_destination을 query constraint로 사용하여 travel_route에 속합니다
end

2.6 Trilogy adapter 도입

Rails 어플리케이션에서 MySQL 호환 데이터베이스 클라이언트인 Trilogy를 원활하게 통합할 수 있도록 새로운 adapter가 도입되었습니다. 이제 Rails 어플리케이션은 config/database.yml 파일을 구성하여 Trilogy 기능을 통합할 수 있는 옵션을 가지게 되었습니다. 예시:

development:
  adapter: trilogy
  database: blog_development
  pool: 5

대안으로, DATABASE_URL environment variable을 사용하여 integration을 달성할 수 있습니다:

ENV["DATABASE_URL"] # => "trilogy://localhost/blog_development?pool=5"

2.7 ActiveSupport::MessagePack 추가

ActiveSupport::MessagePackmsgpack gem과 통합되는 serializer입니다. ActiveSupport::MessagePackmsgpack이 지원하는 기본 Ruby 타입뿐만 아니라 Time, ActiveSupport::TimeWithZone, ActiveSupport::HashWithIndifferentAccess와 같은 여러 추가 타입도 serialize할 수 있습니다. JSONMarshal에 비해 ActiveSupport::MessagePack은 payload 크기를 줄이고 성능을 향상시킬 수 있습니다.

ActiveSupport::MessagePackmessage serializer로 사용될 수 있습니다:

config.active_support.message_serializer = :message_pack

# 또는 개별적으로:
ActiveSupport::MessageEncryptor.new(secret, serializer: :message_pack)
ActiveSupport::MessageVerifier.new(secret, serializer: :message_pack)

cookies serializer와 관련하여:

config.action_dispatch.cookies_serializer = :message_pack

MessagePack serializer를 사용하여 모든 cookie 값을 직렬화합니다.

캐시 Serializer로서도 사용됩니다:

config.cache_store = :file_store, "tmp/cache", { serializer: :message_pack }

# 또는 개별적으로:
ActiveSupport::Cache.lookup_store(:file_store, "tmp/cache", serializer: :message_pack)

2.8 config.autoload_libconfig.autoload_lib_once를 통한 향상된 Autoloading 소개

새로운 설정 메서드인 config.autoload_lib(ignore:)가 도입되었습니다. 이 메서드는 기본적으로 포함되지 않는 lib 디렉토리를 포함시켜 애플리케이션의 autoload 경로를 향상시키는 데 사용됩니다. 또한, 새로운 애플리케이션에서는 config.autoload_lib(ignore: %w(assets tasks))가 생성됩니다.

config/application.rb 또는 config/environments/*.rb에서 호출될 때, 이 메서드는 lib 디렉토리를 config.autoload_pathsconfig.eager_load_paths 모두에 추가합니다. 이 기능은 engine에서는 사용할 수 없다는 점에 유의해야 합니다.

유연성을 보장하기 위해, autoloader가 관리하지 않아야 하는 lib 디렉토리 내의 하위 디렉토리를 지정하는 데 ignore 키워드 인자를 사용할 수 있습니다. 예를 들어, assets, tasks, generators와 같은 디렉토리를 ignore 인자에 전달하여 제외할 수 있습니다:

config.autoload_lib(ignore: %w(assets tasks generators))

lib 디렉토리를 autoload 경로에 추가합니다. 기본적으로 특정 표준 디렉토리들은 제외되는데, 위 예시에서는 lib/assets, lib/tasks, lib/generators를 무시합니다.

config.autoload_lib_once 메서드config.autoload_lib와 비슷하지만, libconfig.autoload_paths 대신 config.autoload_once_paths에 추가한다는 점이 다릅니다.

자세한 내용은 autoloading 가이드를 참조하세요.

2.9 일반적인 async 쿼리를 위한 Active Record API

Active Record API에 비동기 쿼리 지원을 확장하는 중요한 개선이 도입되었습니다. 이 개선은 특히 집계(count, sum 등)와 단일 레코드를 반환하거나 Relation이 아닌 다른 것을 반환하는 모든 메서드에 초점을 맞추어, 그다지 빠르지 않은 쿼리들을 더 효율적으로 처리해야 하는 필요성을 해결합니다.

새로운 API는 다음과 같은 비동기 메서드들을 포함합니다:

  • async_count
  • async_sum
  • async_minimum
  • async_maximum
  • async_average
  • async_pluck
  • async_pick
  • async_ids
  • async_find_by_sql
  • async_count_by_sql

다음은 이러한 메서드 중 하나인 async_count를 사용하여 발행된 게시물의 수를 비동기적으로 계산하는 간단한 예시입니다:

# 동기식 count
published_count = Post.where(published: true).count # => 10

# 비동기식 count
promise = Post.where(published: true).async_count # => #<ActiveRecord::Promise status=pending>
promise.value # => 10

이러한 메서드들은 이러한 작업들을 비동기 방식으로 실행할 수 있게 해주며, 특정 유형의 database 쿼리에 대해 성능을 크게 향상시킬 수 있습니다.

2.10 템플릿의 strict locals 설정 허용

템플릿이 명시적으로 locals를 설정할 수 있도록 하는 새로운 기능이 도입되었습니다. 이 개선사항은 템플릿에 변수를 전달할 때 더 큰 제어와 명확성을 제공합니다.

기본적으로 템플릿은 모든 locals를 키워드 인자로 받아들입니다. 하지만 이제 템플릿 파일 시작 부분에 locals magic comment를 추가하여 템플릿이 허용할 locals를 정의할 수 있습니다.

다음은 작동 방식입니다:

<%# locals: (message:) -%>
<%= message %>

locals의 기본값을 설정할 수도 있습니다:

<%# locals: (message: "Hello, world!") -%>
<%= message %>

Optional keyword arguments를 splat 연산자로 처리할 수 있습니다:

<%# locals: (message: "Hello, world!", **attributes) -%>
<%= tag.p(message, **attributes) %>

locals의 사용을 완전히 비활성화하려면 다음과 같이 할 수 있습니다:

<%# locals: () %>

Action View는 # 접두사가 붙은 주석을 지원하는 모든 템플릿 엔진에서 locals: 매직 코멘트를 처리하며, partial의 모든 라인에서 매직 코멘트를 읽습니다.

주의: keyword 인수만 지원됩니다. positional 또는 block 인수를 정의하면 렌더링 시 Action View Error가 발생합니다.

2.11 Rails.application.deprecators 추가

새로운 Rails.application.deprecators 메서드는 애플리케이션 내의 관리되는 deprecator들의 컬렉션을 반환하며, 개별 deprecator를 쉽게 추가하고 검색할 수 있게 해줍니다:

Rails.application.deprecators[:my_gem] = ActiveSupport::Deprecation.new("2.0", "MyGem")
Rails.application.deprecators[:other_gem] = ActiveSupport::Deprecation.new("3.0", "OtherGem")

collection의 설정은 collection 내의 모든 deprecator에 영향을 미칩니다.

Rails.application.deprecators.debug = true

Rails.application.deprecators[:my_gem].debug  
# => true

Rails.application.deprecators[:other_gem].debug
# => true

모든 deprecator 인스턴스의 debug를 한번에 켤 수 있습니다.

코드의 특정 블록에서 모든 deprecator 경고를 무시하고 싶은 상황이 있을 수 있습니다. deprecators 컬렉션을 사용하면 블록 내에서 모든 deprecator 경고를 쉽게 무시할 수 있습니다:

Rails.application.deprecators.silence do
  Rails.application.deprecators[:my_gem].warn    # 경고 없음 (무시됨)
  Rails.application.deprecators[:other_gem].warn # 경고 없음 (무시됨)  
end

2.12 JSON response.parsed_body에 대한 패턴 매칭 지원

ActionDispatch::IntegrationTest 테스트 블록이 JSON 응답에 대해 response.parsed_body를 호출할 때, 해당 payload는 indifferent access로 사용할 수 있습니다. 이를 통해 Ruby의 패턴 매칭Minitest의 패턴 매칭 지원과의 통합이 가능합니다.

get "/posts.json"

response.content_type         # => "application/json; charset=utf-8" 
response.parsed_body.class    # => Array
response.parsed_body          # => [{"id"=>42, "title"=>"Title"},...]

# response body를 파싱한 결과가 패턴과 일치하는지 검증
assert_pattern { response.parsed_body => [{ id: 42 }] }

get "/posts/42.json"

response.content_type         # => "application/json; charset=utf-8"
response.parsed_body.class    # => ActiveSupport::HashWithIndifferentAccess 
response.parsed_body          # => {"id"=>42, "title"=>"Title"}

# response body를 파싱한 결과가 패턴과 일치하는지 검증 
assert_pattern { response.parsed_body => [{ title: /title/i }] }

2.13 Nokogiri로 response.parsed_body 확장하여 HTML 파싱하기

ActionDispatch::Testing 모듈을 확장하여 HTML response.body 값을 Nokogiri::HTML5::Document 인스턴스로 파싱하는 기능을 지원합니다:

get "/posts"

response.content_type         # => "text/html; charset=utf-8" 
response.parsed_body.class    # => Nokogiri::HTML5::Document
response.parsed_body.to_html  # => "<!DOCTYPE html>\n<html>\n..."

Nokogiri에 새로 추가된 pattern matching 지원과 함께, 내장된 Minitest의 pattern matching 지원은 HTML 응답의 구조와 내용에 대한 테스트 assertions를 작성할 수 있는 기회를 제공합니다.

get "/posts"

html = response.parsed_body # => <html>  
                           #      <head></head>
                           #        <body>
                           #          <main><h1>일부 메인 콘텐츠</h1></main>
                           #        </body>
                           #     </html>

assert_pattern { html.at("main") => { content: "일부 메인 콘텐츠" } }  
assert_pattern { html.at("main") => { content: /content/ } }
assert_pattern { html.at("main") => { children: [{ name: "h1", content: /content/ }] } }

2.14 ActionView::TestCase.register_parser 소개

[ActionView::TestCase 확장][#49194]을 통해 view partial이 렌더링한 내용을 알려진 구조로 파싱할 수 있도록 지원합니다. 기본적으로 rendered_html은 HTML을 Nokogiri::XML::Node로 파싱하고, rendered_json은 JSON을 ActiveSupport::HashWithIndifferentAccess로 파싱하도록 정의되어 있습니다.

test "HTML을 렌더링한다" do
  article = Article.create!(title: "Hello, world")

  render partial: "articles/article", locals: { article: article }

  assert_pattern { rendered_html.at("main h1") => { content: "Hello, world" } }
end

test "JSON을 렌더링한다" do
  article = Article.create!(title: "Hello, world")

  render formats: :json, partial: "articles/article", locals: { article: article }

  assert_pattern { rendered_json => { title: "Hello, world" } }
end

렌더링된 콘텐츠를 RSS로 파싱하려면, RSS::Parser.parse을 호출하도록 등록하세요:

register_parser :rss, -> rendered { RSS::Parser.parse(rendered) }

test "RSS 렌더링" do
  article = Article.create!(title: "Hello, world")

  render formats: :rss, partial: article, locals: { article: article }

  assert_equal "Hello, world", rendered_rss.items.last.title
end

렌더링된 내용을 Capybara::Simple::Node로 파싱하려면, Capybara.string 호출로 :html 파서를 다시 등록하세요:

register_parser :html, -> rendered { Capybara.string(rendered) }

test "HTML을 렌더링한다" do
  article = Article.create!(title: "Hello, world")

  render partial: article 

  rendered_html.assert_css "main h1", text: "Hello, world"
end

3 Railties

자세한 변경 사항은 Changelog를 참조하세요.

3.1 제거된 기능

  • 더 이상 사용되지 않는 bin/rails secrets:setup 명령어가 제거되었습니다.

  • Internet Explorer에서만 사용되는 기본 X-Download-Options 헤더가 제거되었습니다.

3.2 Deprecations

  • Rails.application.secrets 사용이 Deprecate 됩니다.

  • secrets:showsecrets:edit 명령어가 credentials 사용을 위해 Deprecate 됩니다.

  • Rails::Generators::Testing::BehaviourRails::Generators::Testing::Behavior 사용을 위해 Deprecate 됩니다.

3.3 주목할 만한 변경사항

  • 기본적으로 sandbox 모드로 rails console을 시작하는 sandbox_by_default 옵션이 추가되었습니다.

  • 라인 범위로 테스트를 필터링하는 새로운 문법이 추가되었습니다.

  • migrations을 복사하기 위해 rails railties:install:migrations 명령을 실행할 때 대상 데이터베이스를 지정할 수 있는 DATABASE 옵션이 추가되었습니다.

  • rails new --javascript generator에 Bun 지원이 추가되었습니다.

    $ rails new my_new_app --javascript=bun
    
  • 테스트 러너에 느린 테스트를 표시하는 기능이 추가되었습니다.

4 Action Cable

자세한 변경사항은 Changelog를 참조하세요.

4.1 삭제 처리

4.2 지원 중단(Deprecations)

4.3 주요 변경사항

  • 블록에서 브로드캐스트된 모든 메시지를 캡처하는 capture_broadcasts 테스트 헬퍼를 추가했습니다.

  • Redis 연결이 끊어졌을 때 자동으로 재연결하는 기능을 Redis pub/sub adapter에 추가했습니다.

  • ActionCable::Connection::Basebefore_command, after_command, around_command 커맨드 콜백을 추가했습니다.

5 Action Pack

자세한 변경사항은 Changelog를 참조하세요.

5.1 제거사항

  • Request#content_type의 deprecated 동작이 제거되었습니다.

  • config.action_dispatch.trusted_proxies에 단일 값을 할당할 수 있는 deprecated 기능이 제거되었습니다.

  • system testing을 위한 deprecated된 poltergeistwebkit(capybara-webkit) 드라이버 등록이 제거되었습니다.

5.2 지원 중단 사항

  • config.action_dispatch.return_only_request_media_type_on_content_type 지원이 중단됩니다.

  • AbstractController::Helpers::MissingHelperError 지원이 중단됩니다.

  • ActionDispatch::IllegalStateError 지원이 중단됩니다.

  • speaker, vibrate, vr permissions policy directives 지원이 중단됩니다.

  • config.action_dispatch.show_exceptions에서 truefalse 값 대신 :all, :rescuable, :none 사용이 권장됩니다.

5.3 주요 변경사항

  • ActionController::Parametersexclude? 메서드가 추가되었습니다. 이는 include? 메서드의 반대입니다.

  • params에서 직렬화된 값을 추출할 수 있도록 ActionController::Parameters#extract_value 메서드가 추가되었습니다.

  • CSRF 토큰을 저장하고 검색하는 사용자 정의 로직을 사용할 수 있는 기능이 추가되었습니다.

  • system test screenshot 헬퍼에 htmlscreenshot kwargs가 추가되었습니다.

6 Action View

자세한 변경사항은 Changelog를 참조하세요.

6.1 삭제된 것들

  • 더 이상 사용되지 않는 ActionView::Path 상수가 삭제되었습니다.

  • partial에 instance variable을 local로 전달하는 더 이상 사용되지 않는 기능이 삭제되었습니다.

6.2 Deprecations (사용 중단)

Rails가 새로운 버전으로 발전할 때, 이전의 API 또는 기능은 필연적으로 새로운 API로 교체됩니다. 이러한 이전 API 또는 기능이 제거되기 전에, Rails는 사용자에게 먼저 deprecation을 통해 해당 변화를 알려줍니다. Ruby on Rails의 feature가 deprecated 상태가 되면, 다음과 같은 일이 발생합니다:

  1. feature는 현재 버전의 Rails에서 계속 작동합니다.
  2. feature를 사용할 때마다 deprecation 경고가 출력됩니다.
  3. feature는 다음 major 버전의 Rails에서 제거됩니다.

Rails의 deprecation 경고를 관리하는 것은 향후 Rails 업그레이드를 보다 순조롭게 만드는데 도움이 됩니다.

어플리케이션의 deprecation 경고를 설정하는 방법에 대한 자세한 내용은 Configuring Rails Applications를 참조하세요.

6.3 주목할 만한 변경사항

  • checkbox_tagradio_button_tag가 이제 키워드 인자로 checked를 받습니다.

  • HTML <picture> 태그를 생성하는 picture_tag 헬퍼가 추가되었습니다.

  • simple_format 헬퍼가 이제 :sanitize_options 기능을 지원하여, sanitize 과정에 추가 옵션을 설정할 수 있습니다.

    simple_format("<a target=\"_blank\" href=\"http://example.com\">Continue</a>", {}, { sanitize_options: { attributes: %w[target href] } })
    # => "<p><a target=\"_blank\" href=\"http://example.com\">Continue</a></p>"
    

7 Action Mailer

자세한 변경사항은 Changelog를 참조하세요.

7.1 제거하기

7.2 지원 중단

  • config.action_mailer.preview_path가 지원 중단됩니다.

  • assert_enqueued_email_with:args kwarg를 통해 params를 전달하는 것이 지원 중단됩니다. 이제 :params kwarg를 지원하므로, params를 전달할 때는 이를 사용하세요.

7.3 주목할만한 변경사항

  • 여러 개의 preview path를 지원하기 위해 config.action_mailer.preview_paths를 추가했습니다.

  • block 내에서 발송된 모든 이메일을 캡처하기 위해 test helper에 capture_emails를 추가했습니다.

  • 모든 대기 중인 이메일 job을 전송하기 위해 ActionMailer::TestHelperdeliver_enqueued_emails를 추가했습니다.

8 Active Record

자세한 변경사항은 Changelog를 참조하세요.

8.1 제거사항

  • ActiveRecord.legacy_connection_handling 지원이 제거되었습니다.

  • 더 이상 사용되지 않는 ActiveRecord::Base config 접근자가 제거되었습니다.

  • configs_for:include_replicas 지원이 제거되었습니다. 대신 :include_hidden을 사용하세요.

  • 더 이상 사용되지 않는 config.active_record.partial_writes가 제거되었습니다.

  • 더 이상 사용되지 않는 Tasks::DatabaseTasks.schema_file_type이 제거되었습니다.

  • PostgreSQL의 structure dumps에서 --no-comments 플래그가 제거되었습니다.

8.2 지원 중단

  • #remove_connectionname 인자가 지원 중단됩니다.

  • check_pending!가 지원 중단되고 check_all_pending!로 대체됩니다.

  • add_foreign_keydeferrable: true 옵션이 지원 중단되고 deferrable: :immediate로 대체됩니다.

  • TestFixtures#fixture_path가 지원 중단되고 TestFixtures#fixture_paths로 대체됩니다.

  • Base에서 connection_handler로의 위임이 지원 중단됩니다.

  • config.active_record.suppress_multiple_database_warning이 지원 중단됩니다.

  • SQL 문자열 템플릿에서 보간된 바인드 파라미터로 ActiveSupport::Duration을 사용하는 것이 지원 중단됩니다.

  • all_connection_pools가 지원 중단되고 connection_pool_list가 더 명시적으로 변경됩니다.

  • primary key가 :id가 아닐 때 read_attribute(:id)가 primary key를 반환하는 것이 지원 중단됩니다.

  • #mergerewhere 인자가 지원 중단됩니다.

  • alias_attribute로 non-attributes를 별칭 지정하는 것이 지원 중단됩니다.

8.3 주목할 만한 변경사항

  • 여러 fixture 경로를 지원하기 위한 TestFixtures#fixture_paths 추가.

  • has_secure_password 사용 시 authenticate_by 추가.

  • ActiveRecord::Persistenceupdate_attribute! 추가. 이는 update_attribute와 유사하지만 before_* callback이 :abort를 발생시킬 때 ActiveRecord::RecordNotSaved를 발생시킴.

  • insert_all/upsert_all에서 별칭이 지정된 속성 사용 허용.

  • add_index:include 옵션 추가.

  • .unscope(:group).group(fields)의 단축 표현으로 #regroup 쿼리 메서드 추가.

  • SQLite3 adapter에 자동 채워지는 컬럼과 사용자 정의 primary key 지원 추가.

  • SQLite3 데이터베이스 연결에 대한 현대적이고 성능이 좋은 기본값 추가.

  • 컬럼-튜플 구문으로 where 절 지정 허용.

    Topic.where([:title, :author_name] => [["The Alchemist", "Paulo Coelho"], ["Harry Potter", "J.K Rowling"]])
    
  • 자동 생성된 인덱스 이름이 이제 62바이트로 제한됨. MySQL, PostgreSQL, SQLite의 기본 인덱스 이름 길이 제한 내에 맞춰짐.

  • Trilogy 데이터베이스 클라이언트를 위한 adapter 도입.

  • 모든 pool의 모든 연결을 즉시 종료하는 ActiveRecord.disconnect_all! 메서드 추가.

  • PostgreSQL migration 명령에 enum 이름 변경, 값 추가, 값 이름 변경 기능 추가.

  • 레코드의 id 컬럼의 원시 값에 접근하기 위한 ActiveRecord::Base#id_value 별칭 추가.

  • enum에 validation 옵션 추가.

  • ActiveRecord::Encryption의 기본 해시 다이제스트가 이제 SHA256으로 변경됨(encrypts로 정의된 속성에 사용). 기본 설정에서 SHA1에서 변경됨. 이러한 기본값에는 support_sha1_for_non_deterministic_encryption = false가 포함되어 있어, 데이터가 재암호화되지 않은 경우 이전 기본 해시 다이제스트로 암호화된 데이터를 복호화할 수 없게 될 수 있음.

9 Active Storage

자세한 변경사항은 Changelog를 참조하세요.

9.1 삭제

  • Active Storage 설정에서 deprecated된 유효하지 않은 기본 content type들을 제거했습니다.

  • Deprecated된 ActiveStorage::Current#hostActiveStorage::Current#host= 메서드를 제거했습니다.

  • Attachment 컬렉션에 할당할 때의 deprecated된 동작을 제거했습니다. 이제 컬렉션에 추가하는 대신 컬렉션이 교체됩니다.

  • Attachment 연관(association)에서 deprecated된 purgepurge_later 메서드를 제거했습니다.

9.2 Deprecated 기능들

  • Rails.application.config.action_mailer.return_path가 deprecated 되었습니다. 대신 Mail::Message#return_pathMail::Message#return_path=를 사용하세요.

  • Rails.application.config.action_mailer.sender_path가 deprecated 되었습니다. 대신 Mail::Message#senderMail::Message#sender=를 사용하세요.

9.3 주요 변경사항

  • ActiveStorage::Analyzer::AudioAnalyzer는 이제 출력 metadata 해시에 sample_ratetags를 포함합니다.

  • 첨부 파일에 대해 preview 또는 representation 메서드를 호출할 때 미리 정의된 variant를 활용하는 옵션이 추가되었습니다.

  • variant를 선언할 때 variant를 전처리하기 위한 preprocessed 옵션이 추가되었습니다.

  • Active Storage variant를 삭제할 수 있는 기능이 추가되었습니다.

    User.first.avatar.variant(resize_to_limit: [100, 100]).destroy
    

10 Active Model

자세한 변경사항은 Changelog를 참조하세요.

10.1 삭제

10.2 폐기 예정(Deprecations)

  • relation.scoping { where(...) } 형태의 scoping 블록에서 relation 체이닝이 더 이상 지원되지 않습니다. relation.scoping { relation.where(...) } 대신 relation.scoping { where(...) } 를 사용하세요. 49e3b4a

  • DatabaseConfigurations#fetch, DatabaseConfigurations#each 는 폐기 예정입니다. 대신 configurations.configs_for, configurations.each 를 사용하세요. 1f50eba

  • PostgreSQL adapter에서 bigint를 integer로 캐스팅하는 것이 폐기 예정입니다. d279903

  • config.active_record.partial_inserts가 Rails 7.1에서 폐기되고 Rails 7.2에서 제거될 예정입니다. 대신 config.active_record.partial_writes를 사용하세요. 3894d72

  • ActiveRecord::Base.allow_unsafe_raw_sql이 폐기 예정입니다. 534e08b

  • with_attached_* scope에 대한 join dependency는 폐기 예정입니다. 2dd9f04

  • after_commit_everywhere가 폐기 예정입니다. f9a58e3

  • Active Record join association 어댑터 정의에서 join_foreign_key 사용이 폐기 예정입니다. 대신 foreign_key를 사용하세요. ff06810

10.3 주목할 만한 변경사항

  • LengthValidator:in/:within 옵션에 infinite range 지원이 추가되었습니다.

    validates_length_of :first_name, in: ..30
    
  • inclusivity/exclusivity validator에 beginless range 지원이 추가되었습니다.

    validates_inclusion_of :birth_date, in: -> { (..Date.today) }
    
    validates_exclusion_of :birth_date, in: -> { (..Date.today) }
    
  • has_secure_password에 password challenge 지원이 추가되었습니다. 설정 시 password challenge가 저장된 password_digest와 일치하는지 검증합니다.

  • validator가 record 인자 없이 lambda를 받을 수 있게 되었습니다.

    # 이전
    validates_comparison_of :birth_date, less_than_or_equal_to: ->(_record) { Date.today }
    
    # 이후
    validates_comparison_of :birth_date, less_than_or_equal_to: -> { Date.today }
    

11 Active Support

자세한 변경사항은 Changelog를 참조하세요.

11.1 제거된 기능들

  • Enumerable#sum의 deprecated된 override를 제거했습니다.

  • deprecated된 ActiveSupport::PerThreadRegistry를 제거했습니다.

  • Array, Range, Date, DateTime, Time, BigDecimal, Float, Integer에서 #to_s에 format을 전달하는 deprecated된 옵션을 제거했습니다.

  • deprecated된 ActiveSupport::TimeWithZone.name override를 제거했습니다.

  • deprecated된 active_support/core_ext/uri 파일을 제거했습니다.

  • deprecated된 active_support/core_ext/range/include_time_with_zone 파일을 제거했습니다.

  • ActiveSupport::SafeBuffer에 의한 객체들의 String으로의 암시적 변환을 제거했습니다.

  • Digest::UUID에 정의된 상수들 중 하나가 아닌 namespace ID를 제공할 때 부정확한 RFC 4122 UUID를 생성하는 deprecated된 지원을 제거했습니다.

11.2 Deprecations

  • config.active_support.disable_to_s_conversion 사용이 중단될 예정입니다.

  • config.active_support.remove_deprecated_time_with_zone_name 사용이 중단될 예정입니다.

  • config.active_support.use_rfc4122_namespaced_uuids 사용이 중단될 예정입니다.

  • SafeBuffer#clone_empty 사용이 중단될 예정입니다.

  • ActiveSupport::Deprecation 싱글톤의 사용이 중단될 예정입니다.

  • Dalli::Client 인스턴스로 ActiveSupport::Cache::MemCacheStore를 초기화하는 것이 중단될 예정입니다.

  • Notification::Event#children#parent_of? 메서드 사용이 중단될 예정입니다.

11.3 주요 변경사항

12 Active Job

자세한 변경사항은 Changelog를 참조하세요.

12.1 삭제 사항

  • QueAdapter가 제거되었습니다.

12.2 지원 중단

12.3 주목할 만한 변경사항

  • 여러 job을 한 번에 enqueue하기 위한 perform_all_later 추가.

  • job generator에 job의 부모 클래스를 지정하기 위한 --parent 옵션 추가.

  • job이 폐기되기 직전에 실행할 callback을 위한 after_discard 메서드를 ActiveJob::Base에 추가.

  • background job enqueue caller들의 로깅 지원 추가.

13 Action Text

자세한 변경사항은 Changelog를 참조하세요.

13.1 제거

  • The rails test command has been removed in favor of more focused rails test:* commands (Pull Request)

  • 더 집중된 rails test:* 명령어를 이용할 수 있도록 rails test 명령어가 제거되었습니다 (Pull Request)

13.2 지원 종료 예정 기능

13.3 주목할 만한 변경사항

14 Action Mailbox

자세한 변경사항은 Changelog를 참고해 주세요.

14.1 제거

14.2 Deprecations (지원 중단 예정)

Rails에서 지원 중단(deprecate)된 기능이란 여전히 작동하지만 더 이상 적극적으로 지원되지 않으며 향후 Rails 버전에서 제거될 예정인 기능을 의미합니다. 지원 중단 주기를 사용하면 이러한 변경 사항에 대해 사전에 알 수 있으므로, 애플리케이션의 유지보수성과 안정성을 높이기 위해 이러한 기능을 교체할 수 있습니다.

Rails 팀은 하위 호환성을 매우 중요하게 생각하며, 개발자가 새로운 버전으로 업그레이드하는 것이 가능한 쉽도록 노력하고 있습니다. Rails의 deprecation cycle은 통상적으로 지원 중단 경고와 함께 최소 한 번의 마이너 버전을 거친 후에 기능이 제거됨을 의미합니다.

예를 들어 config.action_view.raise_on_missing_translations가 Rails 7.1에서 지원 중단되었다면, 이는 다음을 의미합니다:

  1. 이 옵션은 7.1에서도 계속 작동하지만, 지원 중단 경고가 발생합니다.
  2. 아직 결정되지는 않았지만, 이 옵션은 향후 Rails 버전에서 제거될 수 있습니다.
  3. 언제라도 이 코드 기반을 검토하고 현재 기능과 동등한 대체 기능으로 업데이트할 수 있습니다.

지원 중단 경고는 개발 환경에서 기본적으로 활성화되어 있으며, config.active_support.deprecation 설정을 통해 제어할 수 있습니다.

14.3 주목할 만한 변경사항

  • recipients에 X-Forwarded-To 주소를 추가했습니다.

  • mailer 큐를 거치지 않고 반송 이메일을 보내기 위해 ActionMailbox::Basebounce_now_with 메서드를 추가했습니다.

15 Ruby on Rails 가이드

자세한 변경 사항은 Changelog를 참조하세요.

15.1 주목할 만한 변경사항

16 감사의 글

Rails를 안정적이고 견고한 프레임워크로 만들기 위해 많은 시간을 투자한 수많은 사람들을 보려면 Rails 기여자 전체 목록을 참고하세요. 이 모든 분들께 감사드립니다.



맨 위로