1 Rails 5.1로 업그레이드하기
기존 애플리케이션을 업그레이드하는 경우, 진행하기 전에 충분한 테스트 커버리지를 갖추는 것이 좋습니다. 아직 하지 않았다면 먼저 Rails 5.0으로 업그레이드하고, Rails 5.1로 업데이트를 시도하기 전에 애플리케이션이 예상대로 실행되는지 확인해야 합니다. 업그레이드 시 주의해야 할 사항 목록은 Ruby on Rails 업그레이드하기 가이드에서 확인할 수 있습니다.
2 주요 기능
2.1 Yarn 지원
Rails 5.1은 Yarn을 통해 npm의 JavaScript 의존성을 관리할 수 있게 되었습니다. 이를 통해 React, VueJS 또는 npm 생태계의 다른 라이브러리들을 쉽게 사용할 수 있게 되었습니다. Yarn 지원은 asset pipeline과 통합되어 있어서 모든 의존성이 Rails 5.1 앱에서 원활하게 작동합니다.
2.2 선택적 Webpack 지원
Rails 애플리케이션은 JavaScript 애셋 번들러인 Webpack과 새로운 Webpacker gem을 사용하여 더 쉽게 통합할 수 있습니다. 새로운 애플리케이션을 생성할 때 --webpack
플래그를 사용하여 Webpack 통합을 활성화할 수 있습니다.
이는 이미지, 폰트, 사운드 및 기타 애셋에 계속 사용할 수 있는 asset pipeline과 완벽하게 호환됩니다. 일부 JavaScript 코드는 asset pipeline으로 관리하고, 다른 코드는 Webpack을 통해 처리할 수도 있습니다. 이 모든 것은 기본적으로 활성화되어 있는 Yarn에 의해 관리됩니다.
2.3 jQuery가 더 이상 기본 의존성이 아님
이전 Rails 버전에서는 data-remote
, data-confirm
및 Rails의 Unobtrusive JavaScript 기능의 다른 부분들을 제공하기 위해 jQuery가 기본적으로 필요했습니다. UJS가 순수 바닐라 JavaScript를 사용하도록 재작성되었기 때문에 더 이상 필요하지 않습니다. 이 코드는 이제 Action View 내부에 rails-ujs
로 포함되어 있습니다.
필요한 경우 여전히 jQuery를 사용할 수 있지만, 더 이상 기본적으로 요구되지 않습니다.
2.4 System tests
Rails 5.1은 System test 형태로 Capybara test를 작성하기 위한 내장 지원을 제공합니다. 더 이상 이러한 테스트를 위해 Capybara와 데이터베이스 정리 전략을 구성하는 것에 대해 걱정할 필요가 없습니다. Rails 5.1은 실패 스크린샷과 같은 추가 기능과 함께 Chrome에서 테스트를 실행하기 위한 래퍼를 제공합니다.
2.5 Encrypted secrets
Rails는 이제 sekrets gem에서 영감을 받아 애플리케이션 secrets를 안전한 방법으로 관리할 수 있습니다.
bin/rails secrets:setup
을 실행하여 새로운 암호화된 secrets 파일을 설정하세요. 이는 저장소 외부에 보관해야 하는 마스터 키도 생성합니다. secrets 자체는 암호화된 형태로 버전 관리 시스템에 안전하게 체크인될 수 있습니다.
secrets는 프로덕션 환경에서 RAILS_MASTER_KEY
환경 변수나 키 파일에 저장된 키를 사용하여 복호화됩니다.
2.6 Parameterized mailers
mailer 클래스의 모든 메서드에서 사용되는 공통 parameter들을 지정하여 instance 변수, header 및 기타 공통 설정을 공유할 수 있습니다.
class InvitationsMailer < ApplicationMailer
before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
before_action { @account = params[:inviter].account }
def account_invitation
mail subject: "#{@inviter.name}님이 Basecamp(#{@account.name})에 초대했습니다"
end
end
InvitationsMailer.with(inviter: person_a, invitee: person_b)
.account_invitation.deliver_later
2.7 Direct & resolved routes
Rails 5.1은 라우팅 DSL에 resolve
와 direct
라는 두 개의 새로운 메서드를 추가했습니다. resolve
메서드를 사용하면 모델의 polymorphic 매핑을 커스터마이즈할 수 있습니다.
resource :basket
resolve("Basket") { [:basket] }
resource
단수형으로 정의하면, Rails는 URL에서 식별자를 제거하고 이를 처리할 수 있는 컨트롤러 역시 단수형으로 제공합니다. 이 경우 BasketController
는 사용자별로 고유한 장바구니를 처리할 수 있습니다.
resolve
메서드를 사용하여 Rails가 Basket
모델을 URL 헬퍼로 변환하는 방법을 정의할 수 있습니다. 이는 모델이 URL에 식별자가 필요하지 않을 때 유용합니다.
<%= form_for @basket do |form| %>
<!-- basket form -->
<% end %>
이렇게 하면 일반적인 /baskets/:id
대신 단수형 URL인 /basket
이 생성됩니다.
direct
메서드를 사용하면 커스텀 URL 헬퍼를 생성할 수 있습니다.
direct(:homepage) { "https://rubyonrails.org" }
homepage_url # => "https://rubyonrails.org"
block의 반환값은 url_for
메소드의 유효한 인수여야 합니다. 즉, 유효한 문자열 URL, Hash, Array, Active Model 인스턴스 또는 Active Model 클래스를 전달할 수 있습니다.
direct :commentable do |model|
[ model, anchor: model.dom_id ]
end
direct :main do
{ controller: 'pages', action: 'index', subdomain: 'www' }
end
2.8 form_for와 form_tag의 form_with로의 통합
Rails 5.1 이전에는 HTML form을 다루기 위한 두 가지 인터페이스가 있었습니다:
모델 인스턴스를 위한 form_for
와 사용자 정의 URL을 위한 form_tag
였습니다.
Rails 5.1은 이 두 인터페이스를 form_with
로 통합했으며,
URL, scope 또는 model을 기반으로 form 태그를 생성할 수 있습니다.
URL만 사용하는 경우:
<%= form_with url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# 다음과 같이 생성됩니다 %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="title">
</form>
scope는 input 필드명의 접두사를 추가합니다:
<%= form_with scope: :post, url: posts_path do |form| %>
<%= form.text_field :title %>
<% end %>
<%# 다음과 같이 생성됨 %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
model을 사용하면 URL과 scope를 모두 추론합니다:
<%= form_with model: Post.new do |form| %>
<%= form.text_field :title %>
<% end %>
<%# 다음과 같이 생성됩니다 %>
<form action="/posts" method="post" data-remote="true">
<input type="text" name="post[title]">
</form>
기존 모델이 업데이트 form을 만들고 필드 값을 채웁니다:
<%= form_with model: Post.first do |form| %>
<%= form.text_field :title %>
<% end %>
<%# 다음과 같이 생성됩니다 %>
<form action="/posts/1" method="post" data-remote="true">
<input type="hidden" name="_method" value="patch">
<input type="text" name="post[title]" value="<게시물의 제목>">
</form>
3 Incompatibilities
다음의 변경사항들은 업그레이드시 즉각적인 조치가 필요할 수 있습니다.
3.1 여러 연결에서의 트랜잭션 테스트
이제 트랜잭션 테스트는 모든 Active Record 연결을 데이터베이스 트랜잭션으로 감싸게 됩니다.
테스트가 추가 스레드를 생성하고, 해당 스레드들이 데이터베이스 연결을 획득할 때, 이러한 연결들은 특별하게 처리됩니다:
스레드들은 관리되는 트랜잭션 내부에 있는 하나의 연결을 공유하게 됩니다. 이를 통해 모든 스레드가 가장 바깥쪽 트랜잭션을 무시하고 동일한 상태의 데이터베이스를 볼 수 있습니다. 이전에는 이러한 추가 연결들이 예를 들어 fixture 행들을 볼 수 없었습니다.
스레드가 중첩된 트랜잭션에 진입할 때, 격리를 유지하기 위해 일시적으로 연결의 독점적 사용권을 얻게 됩니다.
현재 테스트가 생성된 스레드에서 트랜잭션 외부의 별도 연결을 얻는 것에 의존하고 있다면, 더 명시적인 연결 관리 방식으로 전환해야 합니다.
테스트가 스레드를 생성하고 해당 스레드들이 명시적 데이터베이스 트랜잭션을 사용하면서 상호작용하는 경우, 이 변경사항으로 인해 교착 상태가 발생할 수 있습니다.
이 새로운 동작을 비활성화하는 쉬운 방법은 영향을 받는 테스트 케이스에서 트랜잭션 테스트를 비활성화하는 것입니다.
4 Railties
자세한 변경사항은 Changelog를 참조하세요.
4.1 제거된 기능들
더 이상 사용되지 않는
config.static_cache_control
제거. (commit)더 이상 사용되지 않는
config.serve_static_files
제거. (commit)더 이상 사용되지 않는 파일
rails/rack/debugger
제거. (commit)더 이상 사용되지 않는 task들 제거:
rails:update
,rails:template
,rails:template:copy
,rails:update:configs
,rails:update:bin
. (commit)routes
task를 위한 더 이상 사용되지 않는CONTROLLER
환경 변수 제거. (commit)rails new
명령어에서 -j (--javascript) 옵션 제거. (Pull Request)
4.2 주요 변경사항
모든 환경에서 로드될
config/secrets.yml
에 공유 섹션을 추가했습니다. (commit)설정 파일
config/secrets.yml
이 이제 모든 키를 심볼로 로드합니다. (Pull Request)기본 스택에서 jquery-rails를 제거했습니다. Action View에 포함된 rails-ujs가 기본 UJS 어댑터로 포함됩니다. (Pull Request)
새로운 앱에 yarn binstub와 package.json으로 Yarn 지원을 추가했습니다. (Pull Request)
--webpack
옵션을 통해 새로운 앱에 Webpack 지원을 추가했습니다. 이는 rails/webpacker gem에 위임됩니다. (Pull Request)--skip-git
옵션이 제공되지 않은 경우 새 앱 생성 시 Git 저장소를 초기화합니다. (Pull Request)config/secrets.yml.enc
에 암호화된 secrets를 추가했습니다. (Pull Request)rails initializers
에서 railtie 클래스 이름을 표시합니다. (Pull Request)
5 Action Cable
자세한 변경사항은 Changelog를 참조하세요.
5.1 주요 변경 사항
여러 애플리케이션에서 동일한 Redis 서버를 사용할 때 이름 충돌을 피하기 위해
cable.yml
의 Redis 및 evented Redis adapter에channel_prefix
지원이 추가되었습니다. (Pull Request)데이터 broadcasting을 위한
ActiveSupport::Notifications
hook이 추가되었습니다. (Pull Request)
6 Action Pack
자세한 변경 사항은 Changelog를 참조하세요.
6.1 제거된 기능
ActionDispatch::IntegrationTest
와ActionController::TestCase
클래스의#process
,#get
,#post
,#patch
,#put
,#delete
,#head
에서 키워드가 아닌 인수에 대한 지원이 제거되었습니다. (Commit, Commit)더 이상 사용되지 않는
ActionDispatch::Callbacks.to_prepare
와ActionDispatch::Callbacks.to_cleanup
이 제거되었습니다. (Commit)controller filter와 관련된 더 이상 사용되지 않는 메서드들이 제거되었습니다. (Commit)
render
에서:text
와:nothing
에 대한 더 이상 사용되지 않는 지원이 제거되었습니다. (Commit, Commit)ActionController::Parameters
에서HashWithIndifferentAccess
메서드를 호출하는 더 이상 사용되지 않는 지원이 제거되었습니다. (Commit)
6.2 폐기 예정
-
config.action_controller.raise_on_unfiltered_parameters
가 폐기 예정입니다. Rails 5.1에서는 아무런 효과가 없습니다. (Commit)
6.3 주요 변경사항
라우팅 DSL에
direct
와resolve
메서드가 추가되었습니다. (Pull Request)애플리케이션에서 system test를 작성할 수 있는 새로운
ActionDispatch::SystemTestCase
클래스가 추가되었습니다. (Pull Request)
7 Action View
자세한 변경사항은 Changelog를 참조하세요.
7.1 제거된 기능
ActionView::Template::Error
에서 deprecated된#original_exception
이 제거되었습니다. (commit)strip_tags
에서 잘못된 이름의 옵션encode_special_chars
가 제거되었습니다. (Pull Request)
7.2 중단 예정
- Erubi를 위해 Erubis ERB handler를 중단 예정(deprecated)으로 지정했습니다. (Pull Request)
7.3 주요 변경사항
Raw template handler(Rails 5의 기본 template handler)가 이제 HTML-safe 문자열을 출력합니다. (commit)
datetime_field
와datetime_field_tag
가datetime-local
필드를 생성하도록 변경되었습니다. (Pull Request)HTML 태그를 위한 새로운 Builder 스타일 문법(
tag.div
,tag.br
등)이 추가되었습니다. (Pull Request)form_tag
와form_for
사용을 통합하기 위해form_with
가 추가되었습니다. (Pull Request)current_page?
에check_parameters
옵션이 추가되었습니다. (Pull Request)
8 Action Mailer
자세한 변경사항은 Changelog를 참조하세요.
8.1 주요 변경사항
attachment가 포함되고 body가 인라인으로 설정된 경우 사용자 지정 content type을 설정할 수 있게 되었습니다. (Pull Request)
default
메소드의 값으로 lambda를 전달할 수 있게 되었습니다. (Commit)서로 다른 mailer action 간에 before filter와 default를 공유하기 위한 매개변수화된 mailer 호출을 지원하도록 추가되었습니다. (Commit)
mailer action으로 들어오는 인수들을
args
키 아래의process.action_mailer
이벤트로 전달하도록 되었습니다. (Pull Request)
9 Active Record
자세한 변경사항은 Changelog를 참조하세요.
9.1 제거된 기능
ActiveRecord::QueryMethods#select
에 인자와 블록을 동시에 전달하는 기능이 제거되었습니다. (Commit)더 이상 사용되지 않는
activerecord.errors.messages.restrict_dependent_destroy.one
과activerecord.errors.messages.restrict_dependent_destroy.many
i18n 스코프가 제거되었습니다. (Commit)단수 및 컬렉션 관계 리더에서 더 이상 사용되지 않는 force-reload 인자가 제거되었습니다. (Commit)
#quote
에 컬럼을 전달하는 더 이상 사용되지 않는 지원이 제거되었습니다. (Commit)#tables
에서 더 이상 사용되지 않는name
인자가 제거되었습니다. (Commit)#tables
와#table_exists?
가 테이블과 뷰를 반환하던 더 이상 사용되지 않는 동작이 제거되어, 이제 뷰가 아닌 테이블만 반환합니다. (Commit)ActiveRecord::StatementInvalid#initialize
와ActiveRecord::StatementInvalid#original_exception
에서 더 이상 사용되지 않는original_exception
인자가 제거되었습니다. (Commit)쿼리에서 클래스를 값으로 전달하는 더 이상 사용되지 않는 지원이 제거되었습니다. (Commit)
LIMIT에서 쉼표를 사용한 쿼리의 더 이상 사용되지 않는 지원이 제거되었습니다. (Commit)
#destroy_all
에서 더 이상 사용되지 않는conditions
파라미터가 제거되었습니다. (Commit)#delete_all
에서 더 이상 사용되지 않는conditions
파라미터가 제거되었습니다. (Commit)더 이상 사용되지 않는
#load_schema_for
메서드가#load_schema
를 위해 제거되었습니다. (Commit)더 이상 사용되지 않는
#raise_in_transactional_callbacks
설정이 제거되었습니다. (Commit)더 이상 사용되지 않는
#use_transactional_fixtures
설정이 제거되었습니다. (Commit)
9.2 Deprecations
error_on_ignored_order
채택을 위해error_on_ignored_order_or_limit
flag를 deprecate 처리했습니다. (Commit)sanitize_sql
채택을 위해sanitize_conditions
를 deprecate 처리했습니다. (Pull Request)connection adapter의
supports_migrations?
를 deprecate 처리했습니다. (Pull Request)Migrator.schema_migrations_table_name
을 deprecate 처리했습니다. 대신SchemaMigration.table_name
을 사용하세요. (Pull Request)quoting과 type casting에서
#quoted_id
사용을 deprecate 처리했습니다. (Pull Request)#index_name_exists?
에default
인자 전달을 deprecate 처리했습니다. (Pull Request)
9.3 주목할 만한 변경사항
Primary Keys의 기본값을 BIGINT로 변경. (Pull Request)
MySQL 5.7.5+ 및 MariaDB 5.2.0+에서 Virtual/generated column 지원. (Commit)
Batch processing에서 limits 지원 추가. (Commit)
Transactional tests가 이제 모든 Active Record connections를 database transactions로 감싸게 됨. (Pull Request)
기본적으로
mysqldump
명령의 출력에서 주석을 건너뛰도록 함. (Pull Request)블록이 인자로 전달될 때
ActiveRecord::Relation#count
가 해당 블록을 무시하지 않고 레코드 카운팅에 Ruby의Enumerable#count
를 사용하도록 수정. (Pull Request)SQL 에러를 숨기지 않도록
psql
명령에"-v ON_ERROR_STOP=1"
플래그 전달. (Pull Request)ActiveRecord::Base.connection_pool.stat
추가. (Pull Request)ActiveRecord::Migration
에서 직접 상속받으면 에러 발생. Migration이 작성된 Rails 버전을 명시해야 함. (Commit)through
association이 모호한 reflection 이름을 가질 때 에러 발생. (Commit)
10 Active Model
자세한 변경사항은 Changelog를 참조하세요.
10.1 삭제된 기능
ActiveModel::Errors
에서 deprecated된 메서드들이 제거되었습니다. (commit)length validator에서 deprecated된
:tokenizer
옵션이 제거되었습니다. (commit)반환값이 false일 때 callback을 중단하는 deprecated된 동작이 제거되었습니다. (commit)
10.2 주요 변경사항
- 모델 attribute에 할당된 원본 문자열이 더 이상 잘못 frozen 되지 않습니다. (Pull Request)
11 Active Job
자세한 변경사항은 Changelog를 참조하세요.
11.1 삭제된 기능
.queue_adapter
에 adapter 클래스를 전달하는 deprecated된 지원이 삭제되었습니다. (commit)ActiveJob::DeserializationError
에서 deprecated된#original_exception
이 삭제되었습니다. (commit)
11.2 주목할 만한 변경사항
ActiveJob::Base.retry_on
과ActiveJob::Base.discard_on
을 통한 선언적 예외 처리를 추가했습니다. (Pull Request)재시도 실패 후 커스텀 로직에서
job.arguments
와 같은 내용에 접근할 수 있도록 job 인스턴스를 yield합니다. (commit)
12 Active Support
자세한 변경사항은 Changelog를 참조하세요.
12.1 제거된 기능
ActiveSupport::Concurrency::Latch
class가 제거되었습니다. (Commit)halt_callback_chains_on_return_false
가 제거되었습니다. (Commit)return 값이 false일 때 callback을 중단하는 deprecated 동작이 제거되었습니다. (Commit)
12.2 Deprecations
최상위 레벨의
HashWithIndifferentAccess
클래스는ActiveSupport::HashWithIndifferentAccess
클래스를 선호하는 방향으로 소프트 디프리케이션 되었습니다. (Pull Request)set_callback
과skip_callback
의 조건부 옵션:if
와:unless
에 문자열을 전달하는 것이 디프리케이션 되었습니다. (Commit)
12.3 주목할만한 변경사항
DST 변경 시에도 일관성을 유지하도록 duration 파싱과 traveling을 수정했습니다. (Commit, Pull Request)
Unicode를 9.0.0 버전으로 업데이트했습니다. (Pull Request)
Duration#before와 #after를 #ago와 #since의 별칭으로 추가했습니다. (Pull Request)
현재 객체에 정의되지 않은 메서드 호출을 프록시 객체에 위임하는
Module#delegate_missing_to
를 추가했습니다. (Pull Request)현재 날짜와 시간의 하루 전체를 나타내는 범위를 반환하는
Date#all_day
를 추가했습니다. (Pull Request)테스트를 위한
assert_changes
와assert_no_changes
메서드를 도입했습니다. (Pull Request)travel
과travel_to
메서드가 중첩 호출 시 예외를 발생시키도록 변경되었습니다. (Pull Request)usec와 nsec를 지원하도록
DateTime#change
를 업데이트했습니다. (Pull Request)
13 감사의 말
Rails를 안정적이고 견고한 프레임워크로 만들기 위해 많은 시간을 투자한 수많은 사람들은 Rails 기여자 전체 목록에서 확인하실 수 있습니다. 모든 분들께 감사드립니다.