Ruby on Rails 2.2 릴리스 노트
Rails 2.2는 여러 가지 새로운 기능과 개선된 기능을 제공합니다. 이 목록에는 주요 업그레이드만 포함되어 있으며 모든 버그 수정 및 변경 사항은 포함되어 있지 않습니다. 모든 내용을 보려면 GitHub의 Rails 주요 저장소에서 커밋 목록을 확인하세요.
Rails와 함께 Ruby on Rails Guides가 출시되었습니다. 이는 진행 중인 Rails Guides hackfest의 첫 번째 결과물입니다. 이 사이트는 Rails의 주요 기능에 대한 고품질 문서를 제공할 것입니다.
인프라
Rails 2.2는 Rails가 원활하게 작동하고 외부 세계와 연결되도록 하는 인프라에 대한 중요한 릴리스입니다.
국제화
Rails 2.2는 국제화(또는 i18n, 타이핑하기 싫어하시는 분들을 위해)를 위한 쉬운 시스템을 제공합니다.
- 주요 기여자: Rails i18 팀
- 더 많은 정보:
Ruby 1.9 및 JRuby와의 호환성
스레드 안전성과 함께 Rails가 JRuby와 향후 Ruby 1.9와 잘 작동하도록 많은 작업이 이루어졌습니다. Ruby 1.9가 계속 변화하고 있기 때문에 최신 Rails를 최신 Ruby에서 실행하는 것은 여전히 성공과 실패가 엇갈리지만, Rails는 Ruby 1.9가 출시될 때 전환할 준비가 되어 있습니다.
문서
Rails의 내부 문서인 코드 주석이 여러 곳에서 개선되었습니다. 또한 Ruby on Rails Guides 프로젝트는 주요 Rails 구성 요소에 대한 정보의 권위 있는 소스입니다. 첫 공식 릴리스에서 Guides 페이지에는 다음이 포함됩니다:
- Rails 시작하기
- Rails 데이터베이스 마이그레이션
- Active Record 연결
- Active Record 쿼리 인터페이스
- Rails의 레이아웃 및 렌더링
- Action View 폼 헬퍼
- Rails 라우팅: 바깥에서 안으로
- Action Controller 개요
- Rails 캐싱
- Rails 애플리케이션 테스트 가이드
- Rails 애플리케이션 보안
- Rails 애플리케이션 디버깅
- Rails 플러그인 기본 만들기
이 Guides는 초보 및 중급 Rails 개발자를 위한 수만 단어의 안내서를 제공합니다.
로컬에서 이 가이드를 생성하려면 애플리케이션 내에서 다음을 실행하세요:
$ rake doc:guides
이렇게 하면 가이드가 Rails.root/doc/guides
에 배치되며 Rails.root/doc/guides/index.html
을 열어 바로 탐색할 수 있습니다.
- Xavier Noria와 Hongli Lai의 주요 기여.
- 더 많은 정보:
HTTP와 더 나은 통합: 기본 제공 ETag 지원
HTTP 헤더의 ETag와 마지막 수정 타임스탬프를 지원하면 Rails에서 최근에 수정되지 않은 리소스에 대한 요청에 빈 응답을 보낼 수 있습니다. 이를 통해 응답을 보내야 하는지 여부를 확인할 수 있습니다.
class ArticlesController < ApplicationController def show_with_respond_to_block @article = Article.find(params[:id]) # stale?에 제공된 옵션과 요청 헤더가 다른 경우 요청이 실제로 오래되었으며 respond_to 블록이 트리거됩니다(그리고 stale? 호출의 옵션이 응답에 설정됩니다). # # 요청 헤더가 일치하는 경우 요청이 최신이며 respond_to 블록이 트리거되지 않습니다. 대신 기본 렌더링이 발생하며, last-modified 및 etag 헤더를 확인하고 템플릿을 렌더링하는 대신 "304 Not Modified"만 보냅니다. if stale?(:last_modified => @article.published_at.utc, :etag => @article) respond_to do |wants| # 일반적인 응답 처리 end end end def show_with_implied_render @article = Article.find(params[:id]) # 응답 헤더를 설정하고 요청과 확인합니다. 요청이 오래된 경우(즉, etag 또는 last-modified가 일치하지 않는 경우) 기본 템플릿 렌더링이 발생합니다. # 요청이 최신인 경우 기본 렌더링이 "304 Not Modified"를 반환합니다. fresh_when(:last_modified => @article.published_at.utc, :etag => @article) end end
스레드 안전성
Rails 2.2에서는 Rails를 스레드 안전하게 만드는 작업이 진행되고 있습니다. 웹 서버 인프라에 따라 이를 통해 메모리의 Rails 복사본을 줄이고 더 많은 요청을 처리할 수 있어 서버 성능이 향상되고 다중 코어 활용도가 높아집니다.
프로덕션 모드의 애플리케이션에서 다중 스레드 디스패칭을 활성화하려면 config/environments/production.rb
에 다음 줄을 추가하세요:
config.threadsafe!
Active Record
여기에는 두 가지 큰 추가 사항이 있습니다: 트랜잭션 마이그레이션과 풀링된 데이터베이스 트랜잭션. 또한 조인 테이블 조건에 대한 새로운(그리고 더 깨끗한) 구문이 있으며, 몇 가지 작은 개선 사항도 있습니다.
트랜잭션 마이그레이션
역사적으로 다단계 Rails 마이그레이션은 문제의 원천이었습니다. 마이그레이션 중 무언가 잘못되면 오류 전의 모든 것이 데이터베이스를 변경했고 오류 후의 모든 것은 적용되지 않았습니다. 또한 마이그레이션 버전이 실행된 것으로 저장되었기 때문에 문제를 해결한 후 rake db:migrate:redo
로 단순히 다시 실행할 수 없었습니다. 트랜잭션 마이그레이션은 이를 변경하여 마이그레이션 단계를 DDL 트랜잭션으로 래핑합니다. 따라서 그 중 하나라도 실패하면 전체 마이그레이션이 취소됩니다. Rails 2.2에서는 PostgreSQL에서 트랜잭션 마이그레이션이 기본적으로 지원됩니다. 이 코드는 향후 다른 데이터베이스 유형으로 확장할 수 있으며 IBM은 이미 DB2 어댑터에 대한 지원을 확장했습니다.
- 주요 기여자: Adam Wiggins
- 더 많은 정보:
연결 풀링
연결 풀링을 통해 Rails는 최대 크기(기본값 5, database.yml
에 pool
키를 추가하여 조정 가능)까지 성장하는 데이터베이스 연결 풀에 걸쳐 데이터베이스 요청을 배포할 수 있습니다. 이를 통해 많은 동시 사용자를 지원하는 애플리케이션의 병목 현상을 제거할 수 있습니다. wait_timeout
도 기본값 5초로 설정되어 있습니다. ActiveRecord::Base.connection_pool
을 통해 풀에 직접 액세스할 수 있습니다.
development: adapter: mysql username: root database: sample_development pool: 10 wait_timeout: 10
- 주요 기여자: Nick Sieger
- 더 많은 정보:
해시를 사용한 조인 테이블 조건
이제 해시를 사용하여 조인 테이블에 대한 조건을 지정할 수 있습니다. 복잡한 조인을 통해 쿼리해야 하는 경우 이는 큰 도움이 됩니다.
class Photo < ActiveRecord::Base belongs_to :product end class Product < ActiveRecord::Base has_many :photos end # 저작권이 없는 사진이 있는 모든 제품 가져오기: Product.all(:joins => :photos, :conditions => { :photos => { :copyright => false }})
- 더 많은 정보:
새로운 동적 파인더
Active Record의 동적 파인더 제품군에 두 가지 새로운 메서드 집합이 추가되었습니다.
find_last_by_attribute
find_last_by_attribute
메서드는 Model.last(:conditions => {:attribute => value})
와 동등합니다.
# 런던에서 가입한 마지막 사용자 가져오기 User.find_last_by_city('London')
- 주요 기여자: Emilio Tagua
find_by_attribute!
새로운 뱅 버전인 find_by_attribute!
는 Model.first(:conditions => {:attribute => value}) || raise ActiveRecord::RecordNotFound
와 동등합니다. 일치하는 레코드를 찾을 수 없는 경우 nil
을 반환하는 대신 이 메서드는 일치하는 항목을 찾을 수 없는 경우 예계속해서 한국어 번역문을 제공합니다:
find_by_attribute!
새로운 뱅 버전인 find_by_attribute!
는 Model.first(:conditions => {:attribute => value}) || raise ActiveRecord::RecordNotFound
와 동등합니다. 일치하는 레코드를 찾을 수 없는 경우 nil
을 반환하는 대신 이 메서드는 일치하는 항목을 찾을 수 없는 경우 예외를 발생시킵니다.
# 'Moby'가 아직 가입하지 않은 경우 ActiveRecord::RecordNotFound 예외 발생! User.find_by_name!('Moby')
- 주요 기여자: Josh Susser
연결이 개인/보호된 범위를 존중합니다
Active Record 연결 프록시는 이제 프록시된 객체의 메서드 범위를 존중합니다. 이전에는(사용자가 hasone :account를 가진 경우) `@user.account.privatemethod를 호출하면 연결된 Account 객체의 private 메서드를 호출할 수 있었습니다. Rails 2.2에서는 이렇게 할 수 없습니다. 이 기능이 필요한 경우
@user.account.send(:privatemethod)를 사용해야 합니다(또는 메서드를 private 대신 public으로 만들어야 합니다).
methodmissing을 재정의하는 경우 연결이 정상적으로 작동하도록
respond_to`도 재정의해야 합니다.
- 주요 기여자: Adam Milligan
- 더 많은 정보:
기타 Active Record 변경 사항
rake db:migrate:redo
는 이제 특정 마이그레이션을 다시 실행하기 위한 선택적 VERSION을 허용합니다.config.active_record.timestamped_migrations = false
를 설정하면 마이그레이션에 UTC 타임스탬프 대신 숫자 접두사가 사용됩니다.- 더 이상 연결 캐시 열을 0으로 초기화할 필요가 없습니다(
:counter_cache => true
로 선언된 연결의 경우). ActiveRecord::Base.human_name
은 모델 이름에 대한 국제화 지원 인간 번역을 제공합니다.
Action Controller
컨트롤러 측에서는 라우팅을 정리하는 데 도움이 되는 여러 변경 사항이 있습니다. 또한 복잡한 애플리케이션의 메모리 사용량을 줄이기 위한 라우팅 엔진의 내부 변경 사항도 있습니다.
얕은 라우트 중첩
얕은 라우트 중첩은 잘 알려진 깊게 중첩된 리소스 사용의 어려움에 대한 해결책을 제공합니다. 얕은 중첩을 사용하면 작업하려는 리소스를 고유하게 식별하는 데 필요한 정보만 제공하면 됩니다.
map.resources :publishers, :shallow => true do |publisher| publisher.resources :magazines do |magazine| magazine.resources :photos end end
이를 통해 다음과 같은 라우트를 인식할 수 있습니다:
/publishers/1 ==> publisher_path(1) /publishers/1/magazines ==> publisher_magazines_path(1) /magazines/2 ==> magazine_path(2) /magazines/2/photos ==> magazines_photos_path(2) /photos/3 ==> photo_path(3)
- 주요 기여자: S. Brent Faulkner
- 더 많은 정보:
멤버 또는 컬렉션 라우트에 대한 메서드 배열
이제 새 멤버 또는 컬렉션 라우트에 대해 메서드 배열을 제공할 수 있습니다. 이를 통해 둘 이상의 동사를 처리해야 하는 경우 즉시 라우트를 모든 동사에 대해 열어둘 필요가 없어집니다. Rails 2.2에서는 다음과 같은 라우트 선언이 합법적입니다:
map.resources :photos, :collection => { :search => [:get, :post] }
- 주요 기여자: Brennan Dunn
특정 작업이 있는 리소스
기본적으로 map.resources
를 사용하여 라우트를 생성하면 Rails는 7개의 기본 작업(index, show, create, new, edit, update, destroy)에 대한 라우트를 생성합니다. 그러나 이러한 각 라우트는 애플리케이션의 메모리를 차지하고 Rails가 추가 라우팅 논리를 생성하게 합니다. 이제 :only
및 :except
옵션을 사용하여 Rails가 리소스에 대해 생성할 라우트를 세부적으로 조정할 수 있습니다. 단일 작업, 작업 배열 또는 특수 :all
또는 :none
옵션을 제공할 수 있습니다. 이러한 옵션은 중첩된 리소스에 상속됩니다.
map.resources :photos, :only => [:index, :show] map.resources :products, :except => :destroy
- 주요 기여자: Tom Stuart
기타 Action Controller 변경 사항
- 이제 요청 라우팅 중 발생한 예외에 대한 사용자 지정 오류 페이지를 쉽게 표시할 수 있습니다.
- HTTP Accept 헤더가 기본적으로 비활성화되었습니다. 원하는 형식을 나타내기 위해
/customers/1.xml
과 같은 형식화된 URL을 사용해야 합니다. Accept 헤더가 필요한 경우config.action_controller.use_accept_header = true
로 다시 활성화할 수 있습니다. - 벤치마킹 숫자는 이제 작은 초 단위 대신 밀리초 단위로 보고됩니다.
- Rails는 이제 HTTP 전용 쿠키(세션에 사용됨)를 지원하며, 이를 통해 최신 브라우저의 일부 크로스 사이트 스크립팅 위험을 완화할 수 있습니다.
redirect_to
는 이제 URI 스키마(예:svn+ssh:
URI)를 완전히 지원합니다.render
는 이제 일반 JavaScript를 올바른 MIME 유형으로 렌더링하는:js
옵션을 지원합니다.- 요청 위조 보호가 HTML 형식 콘텐츠 요청에만 적용되도록 강화되었습니다.
- 다형성 URL은 전달된 매개변수가 nil인 경우 더 합리적으로 동작합니다. 예를 들어
polymorphic_path([@project, @date, @area])
에서 날짜가 nil인 경우project_area_path
를 제공합니다.
Action View
javascript_include_tag
및stylesheet_link_tag
는:recursive
옵션을 지원하여:all
과 함께 사용하면 단일 코드 줄로 전체 파일 트리를 로드할 수 있습니다.- 포함된 Prototype JavaScript 라이브러리가 1.6.0.3 버전으로 업그레이드되었습니다.
RJS#page.reload
를 통해 JavaScript로 브라우저의 현재 위치를 다시 로드할 수 있습니다.atom_feed
헬퍼에 XML 처리 지침을 삽입할 수 있는:instruct
옵션이 추가되었습니다.
Action Mailer
Action Mailer는 이제 메일러 레이아웃을 지원합니다. CustomerMailer
클래스가 layouts/customer_mailer.html.erb
를 사용하는 것처럼 HTML 이메일을 브라우저 보기만큼 멋지게 만들 수 있습니다.
- 더 많은 정보:
Action Mailer는 이제 Ruby 1.8.7이 설치된 경우 GMail의 SMTP 서버에 대한 기본 지원을 제공하여 STARTTLS를 자동으로 켭니다.
Active Support
Active Support는 이제 Rails 애플리케이션에 대한 기본 제공 메모화, each_with_object
메서드, 델리게이트에 대한 접두사 지원 및 기타 다양한 새로운 유틸리티 메서드를 제공합니다.
메모화
메모화는 메서드를 한 번 초기화하고 반복 사용을 위해 해당 값을 저장하는 패턴입니다. 아마도 애플리케이션에서 이 패턴을 사용해 보셨을 것입니다:
def full_name @full_name ||= "#{first_name} #{last_name}" end
메모화를 통해 이 작업을 선언적으로 처리할 수 있습니다:
extend ActiveSupport::Memoizable def full_name "#{first_name} #{last_name}" end memoize :full_name
메모화의 다른 기능에는 unmemoize
, unmemoize_all
및 memoize_all
이 있어 메모화를 켜거나 끌 수 있습니다.
- 주요 기여자: Josh Peek
- 더 많은 정보:
eachwithobject
each_with_object
메서드는 Ruby 1.9에서 백포트된 메서드를 사용하여 inject
에 대한 대안을 제공합니다. 컬렉션을 반복하면서 현재 요소와 메모를 블록에 전달합니다.
%w(foo bar).each_with_object({}) { |str, hsh| hsh[str] = str.upcase } # => {'foo' => 'FOO', 'bar' => 'BAR'}
주요 기여자: Adam Keys
접두사가 있는 델리게이트
클래스에서 다른 클래스로 동작을 위임하는 경우 위임된 메서드를 식별하기 위한 접두사를 지정할 수 있습니다. 예를 들어:
class Vendor < ActiveRecord::Base has_one :account delegate :email, :password, :to => :account, :prefix => true end
이렇게 하면 vendor#account_email
및 vendor#account_password
와 같은 위임된 메서드가 생성됩니다. 사용자 지정 접두사를 지정할 수도 있습니다:
class Vendor < ActiveRecord::Base has_one :account delegate :email, :password, :to => :account, :prefix => :owner end
이렇게 하면 vendor#owner_email
및 vendor#owner_password
와 같은 위임된 메서드가 생성됩니다.
주요 기여자: Daniel Schierbeck
기타 Active Support 변경 사항
ActiveSupport::Multibyte
에 대한 광범위한 업데이트, 여기에는 Ruby 1.9 호환성 수정 사항이 포함됩니다.ActiveSupport::Rescuable
의 추가를 통해 모든 클래스가rescue_from
구문을 믹스인할 수 있습니다.Date
및네, 계속해서 한국어 번역문을 제공하겠습니다:
기타 Active Support 변경 사항
ActiveSupport::Multibyte
에 대한 광범위한 업데이트, 여기에는 Ruby 1.9 호환성 수정 사항이 포함됩니다.ActiveSupport::Rescuable
의 추가를 통해 모든 클래스가rescue_from
구문을 믹스인할 수 있습니다.Date
및Time
클래스에 대한past?
,today?
및future?
를 통해 날짜/시간 비교를 용이하게 합니다.Array#second
부터Array#fifth
까지Array#[1]
부터Array#[4]
의 별칭- 컬렉션의 크기가 1보다 큰지 확인하는
Enumerable#many?
- URL에 사용할 수 있는 입력의 버전을 생성하는
Inflector#parameterize
- 분수 일 및 주를 인식하는
Time#advance
를 통해1.7.weeks.ago
,1.5.hours.since
등을 수행할 수 있습니다. - 포함된 TzInfo 라이브러리가 0.3.12 버전으로 업그레이드되었습니다.
ActiveSupport::StringInquirer
를 통해 문자열 간 비교를 쉽게 수행할 수 있습니다:ActiveSupport::StringInquirer.new("abc").abc? => true
Railties
Railties(Rails 자체의 핵심 코드)에서 가장 큰 변화는 config.gems
메커니즘입니다.
config.gems
배포 문제를 방지하고 Rails 애플리케이션을 더 자체 포함적으로 만들기 위해 /vendor/gems
에 Rails 애플리케이션에 필요한 모든 gem의 사본을 배치할 수 있습니다. 이 기능은 Rails 2.1에 처음 나타났지만 Rails 2.2에서는 훨씬 더 유연하고 견고해졌으며, gem 간의 복잡한 종속성을 처리합니다. Rails의 gem 관리에는 다음과 같은 명령이 포함됩니다:
config/environment.rb
파일에config.gem _gem_name_
- 구성된 모든 gem과 설치, 동결 또는 프레임워크(프레임워크 gem은 gem 종속성 코드가 실행되기 전에 Rails에 의해 로드되는 gem이며 이러한 gem은 동결할 수 없음) 여부를 나열하는
rake gems
- 누락된 gem을 컴퓨터에 설치하는
rake gems:install
/vendor/gems
에 필요한 gem의 사본을 배치하는rake gems:unpack
/vendor/gems
에 필요한 gem과 해당 종속성의 사본을 가져오는rake gems:unpack:dependencies
- 누락된 네이티브 확장을 빌드하는
rake gems:build
- Rails 2.1로 생성된 벤더 gem을 Rails 2.2 방식으로 저장하는
rake gems:refresh_specs
GEM=_gem_name_
을 명령줄에 지정하여 단일 gem을 압축 해제하거나 설치할 수 있습니다.
- 주요 기여자: Matt Jones
- 더 많은 정보:
기타 Railties 변경 사항
- Thin 웹 서버의 팬이라면
script/server
가 이제 Thin을 직접 지원한다는 사실에 기쁠 것입니다. script/plugin install <plugin> -r <revision>
이 이제 git 기반 및 svn 기반 플러그인에서 작동합니다.script/console
에--debugger
옵션이 추가되었습니다.- Rails 자체를 빌드하는 지속적인 통합 서버를 설정하는 지침이 Rails 소스에 포함되어 있습니다.
rake notes:custom ANNOTATION=MYFLAG
를 통해 사용자 지정 주석을 나열할 수 있습니다.Rails.env
를StringInquirer
로 래핑하여Rails.env.development?
와 같이 사용할 수 있습니다.- 감소 경고를 제거하고 gem 종속성을 적절히 처리하기 위해 Rails는 이제 rubygems 1.3.1 이상을 요구합니다.
Deprecated
이 릴리스에서는 몇 가지 오래된 코드가 더 이상 사용되지 않습니다:
Rails::SecretKeyGenerator
가ActiveSupport::SecureRandom
로 대체되었습니다.render_component
는 더 이상 사용되지 않습니다. 이 기능이 필요한 경우 render_components 플러그인을 사용할 수 있습니다.부분 렌더링 시 암시적 로컬 할당이 더 이상 사용되지 않습니다.
def partial_with_implicit_local_assignment @customer = Customer.new("Marcel") render :partial => "customer" end
이전에는 위 코드에서
customer
라는 로컬 변수를 ‘customer’ 부분에서 사용할 수 있었습니다. 이제 모든 변수는:locals
해시를 통해 명시적으로 전달해야 합니다.country_select
가 제거되었습니다. 자세한 내용과 플러그인 대체 방법은 감소 페이지를 참조하세요.ActiveRecord::Base.allow_concurrency
는 더 이상 효과가 없습니다.ActiveRecord::Errors.default_error_messages
가I18n.translate('activerecord.errors.messages')
로 대체되었습니다.%s
및%d
보간 구문은 더 이상 사용되지 않습니다.String#chars
가String#mb_chars
로 대체되었습니다.분수 월 또는 분수 년 지속 기간은 더 이상 사용되지 않습니다. 대신 Ruby의 핵심
Date
및Time
클래스 산술을 사용하세요.Request#relative_url_root
는 더 이상 사용되지 않습니다. 대신ActionController::Base.relative_url_root
를 사용하세요.
크레딧
릴리스 노트는 Mike Gunderloy가 작성했습니다.