RoR Lab Lecture 67~69
Rails Routing from Outside In
[Screen Casts]
- Rails Routing from the Outside In (1) : http://youtu.be/rfeFsnlMVUQ
- Rails Routing from the Outside In (2) : http://youtu.be/l9KM19q7DWs
- Rails Routing from the Outside In (3) : http://youtu.be/AdoXNTJov6Q
* 스크린 캐스트 정보
- 주최 : Ruby On Rails Korea(https://www.facebook.com/groups/rubyonrailskorea/)
- 후원 : Naver D2(https://www.facebook.com/naverd2)
5. Generating Paths and URLs from Code
Basic Sample Code
# in config/routes.rb
get '/patients/:id', to: 'patient#show', as: 'patient'
RUBY
# in controller
@patient = Patient.find(17)
RUBY
# in view
<%= link_to 'Patient Record', patient_path(@patient) %>
# router will generate the path /patients/17
ERB
뷰의 불안정성을 감소
코드를 이해하기 쉽게 유지
헬퍼에 id를 지정하지 않아도 된다는 점에 주목
·
·
·
5/98
6. Resourceful Routing
The Rails Default
# in config/routes.rb
resources :photos
RUBY
한 줄의 코드로 리소스 라우팅을 위한 일반적인 라우트를 빠르게 선언
index, show, new, edit, create, update, destroy (7개)
·
·
6/98
7. Resourceful Routing
CRUD in Rails
CRUD Actions HTTP Verb Action
C(Create) POST create
R(Read/Retrieve) GET index, show
U(Update) PATCH/PUT update
Delete DELETE destroy
Template Actions HTTP Verb Action
GET new
GET edit
7/98
9. Resourceful Routing
CRUD in Rails: Example
HTTP Verb Path Controller#Action Used for
GET (R) /photos photos#index photos의 목록을 표시
GET (T) /photos/new photos#new 새 photo를 생성하기 위한 HTML form
POST (C) /photos photos#create 새 photo를 생성
GET (R) /photos/:id photos#show id가 :id인 photo를 표시
GET (T) /photos/:id/edit photos#edit id가 :id인 photo를 편집하기 위한 HTML form
PATCH/PUT (U) /photos/:id photos#update id가 :id인 photo의 정보를 업데이트
DELETE (D) /photos/:id photos#destroy id가 :id인 photo를 삭제
9/98
10. Resourceful Routing
CRUD in Rails: Path Helper and URL Helper
# Path Helper
{action_name}_{resource_name}_path
# URL Helper
{action_name}_{resource_name}_url
RUBY
Path Helper는 해당 리소스 액션의 path만을 반환
URL Helper는 Path와 함께 현재의 호스트, 포트 등 부가 정보를 함께 반환
·
·
10/98
11. Resourceful Routing
Path Helpers
Path Helper Path Actions Used for
photos_path /photos photos#index photos의 목록을 표시
new_photo_path /photos/new photos#new 새 photo를 생성하기 위한 HTML form
photo_path(:id) /photos/:id photos#show id가 :id인 photo를 표시
edit_photo_path(:id) /photos/:id/edit photos#edit id가 :id인 photo를 편집하기 위한 HTML form
11/98
12. Resourceful Routing
Defining Multiple Resources at the Same Time
# in config/routes.rb
resources :photos
resources :books
resources :videos
RUBY
# in config/routes.rb
# Defining Multiple Resource at the Same Time
resources :photos, :books, :videos
RUBY
12/98
13. Resourceful Routing
Singular Resources
# in config/routes.rb
resource :geocoder
RUBY
id를 참조하지 않고 조회하는 자원의 경우
index, show, new, edit, create, update, destroy (6개)
복수형 컨트롤러에 매핑됨: 단수형과 복수형 리소스를 함께 사용하고자 할 수 있기 때문
·
·
·
13/98
14. Resourceful Routing
Singular Resource Mapping: Example
HTTP Verb Path Controller#Action Used for
GET (T) /geocoder/new geocoderss#new 새 geocoder를 생성하기 위한 HTML form
POST (C) /geocoder geocoders#create 새 geocoder를 생성
GET (R) /geocoder geocoders#show geocoder를 표시
GET (T) /geocoder/edit geocoders#edit geocoder를 편집하기 위한 HTML form
PATCH/PUT (U) /geocoder gecoders#update geocoder의 정보를 업데이트
DELETE (D) /geocoder geocoders#destroy geocoder를 삭제
14/98
15. Resourceful Routing
단수형, 복수형 리소스 동시에 사용하기
# in config/routes.rb
resource :photo
resources :photos
RUBY
동일 컨트롤러(PhotosController)· 에 매핑되는 단수형과 복수형 라우트를 동시에 생성
15/98
16. Resourceful Routing
Path Helpers: for Singular Resource
Path Helper Path Actions Used for
new_geocoder_path /geocoder/new geocoders#new 새 geocoder를 생성하기 위한 HTML form
geocoder_path /geocoder geocoders#show geocoder를 표시
edit_geocoder_path /geocoders/edit geocoders#edit geocoder를 편집하기 위한 HTML form
16/98
17. Resourceful Routing
Namespace and Routing
# in config/routes.rb
namespace :admin do
resources :posts, :comments
end
RUBY
# in app/controllers/admin/posts_controller.rb
class Admin::PostsController < ApplicationController
# class codes
end
RUBY
컨트롤러의 묶음을 네임스페이스 아래 정리하고자 할 때
예: admin 관련 컨트롤러들을 Admin:: 네임스페이스 아래 묶음
·
·
17/98
18. Resourceful Routing
Namespaced Resource Mapping: Example
HTTP Verb Path Controller#Action Named Helper
GET (R) /admin/postss admin/posts#index admin_posts_path
GET (T) /admin/posts/new admin/posts#new new_admin_post_path
POST (C) /admin/posts admin/posts#create admin_posts_path
GET (R) /admin/posts/:id admin/posts#show admin_post_path(:id)
GET (T) /admin/posts/:id/edit admin/posts#edit edit_admin_post_path(:id)
PATCH/PUT (U) /admin/posts/:id admin/posts#update admin_post_path(:id)
DELETE (D) /admin/photos/:id admin/posts#destroy admin_post_path(:id)
18/98
19. Resourceful Routing
Namespace and Routing: Using scope module
# in config/routes.rb
scope module: 'admin' do
resources :posts, :comments
end
RUBY
# in config/routes.rb
resources :posts, module: 'admin'
RUBY
특정 모듈 접두사가 붙은 컨트롤러를 접두사 없이 라우트하고 싶을 때
예: Admin:: 접두사가 붙은 모듈을 접두사(/admin) 없이 라우트
·
·
19/98
20. Resourceful Routing
Namespace and Routing: Using scope
# in config/routes.rb
scope 'admin' do
resources :posts, :comments
end
RUBY
# in config/routes.rb
resources :posts, path: '/admin/posts'
RUBY
특정 모듈 접두사가 없는 컨트롤러를 접두사를 붙여 라우트하고 싶을 때
예: 모듈 접두사 없는 컨트롤러 PostsController를 접두사를 붙여 /admin/posts로 라우트
·
·
20/98
21. Resourceful Routing
Namespaced Resource Mapping: Scope Example
HTTP Verb Path Controller#Action Named Helper
GET (R) /admin/postss posts#index posts_path
GET (T) /admin/posts/new posts#new new_post_path
POST (C) /admin/posts posts#create posts_path
GET (R) /admin/posts/:id posts#show post_path(:id)
GET (T) /admin/posts/:id/edit posts#edit edit_post_path(:id)
PATCH/PUT (U) /admin/posts/:id posts#update post_path(:id)
DELETE (D) /admin/photos/:id posts#destroy post_path(:id)
21/98
22. 잠깐만... 놓치고 간 내용
라우트는 선언 순서가 중요
# in config/routes.rb
get '/patients/:id', to: 'patients#show', as: 'patient'
get '/patients/test'
RUBY
# in config/routes.rb
get '/patients/test'
get '/patients/:id', to: 'patients#show', as: 'patient'
RUBY
상단 routes.rb 코드로는 PatientsController의 test 액션을 실행할 방법이 없음
하단 routes.rb 코드처럼 작성해야 PatientsController의 test 액션에 도달 가능
routes.rb 파일 작성시 순서가 중요함
·
·
·
22/98
23. Resourceful Routing
Nested Resources
class Magazine < ActiveRecord::Base
has_many :ads
end
class Ad < ActiveRecord::Base
belongs_to :magazine
end
RUBY
# in config/routes.rb
resources :magazines do
resources :ads
end
RUBY
논리적으로 자식인 리소스를 중첩하는 방법
중첩 라우트는 라우팅의 관계를 캡쳐할 수 있게 해 준다
본 라우트는 magazines를 위한 라우트이며 동시에 ads를 AdsController에 라우트
ad의 URL은 magazine을 필요로 함
·
·
·
·
23/98
24. Resourceful Routing
Nested Resource CRUD: Example
HTTP Verb Path Controller#Action Used for
GET (R) /magazines/:magazine_id/ads ads#index 특정 magazine의 모든 하위 ads의 목록을 표시
GET (T) /magazines/:magazine_id/ads/new ads#new 특정 magazine에 속한 ad를 생성하기 위한 HTML form
POST (C) /magazines/:magazine_id/ads ads#create 특정 magazine에 속한 새로운 ad를 생성
GET (R) /magazines/:magazine_id/ads/:id ads#show 특정 magazine에 속한 지정된 ad를 표시
GET (T) /magazines/:magazine_id/ads/:id/edit ads#edit 특정 magazine에 속한 지정된 ad를 수정하기 위한 HTML form
PATCH/PUT
(U) /magazines/:magazine_id/ads/:id ads#update 특정 magazine에 속한 지정된 ad를 업데이트
DELETE (D) /magazines/:magazine_id/ads/:id ad#destroy 특정 magazine에 속한 지정된 ad를 삭제
24/98
25. Resourceful Routing
Limits to Nesting
# in config/routes.rb
resources :publishers do
resources :magazines do
resources :photos
end
end
RUBY
원한다면, 다른 중첩된 리소스 안에 리소스를 중첩할 수 있다
깊게 중첩된 라우트는 급속도로 복잡해진다
·
·
25/98
26. Resourceful Routing
Limits to Nesting
# Path Example of Complex Nesting
# /publishers/1/magazines/2/photos/3
# Corresponding route helper would be:
publisher_magazine_photo_url(@publisher, @magazine, @photo)
publisher_magazine_photo_path(@publisher, @magazine, @photo)
RUBY
중첩된 레벨 수만큼의 객체 모두를 지정해야 하며, 레벨이 깊어질만큼 혼란스러워진다
리소스는 레빌 1 이상으로 중첩되어서는 안된다고 권고
·
·
26/98
27. Resourceful Routing
Nested Resources: Shallow Nesting
# in config/routes.rb
resources :posts do
resources :comments, only: [:index, :new, :create]
end
resources :comments, only: [:show, :edit, :update, :destroy]
RUBY
깊은 중첩을 피하기 위해, 부모 아래 범주화된 액션의 컬렉션을 생성
멤버 액션을 중첩하지 않고 계층의 의미를 갖게 함
최소한의 정보로 고유하게 리소스를 식별하는 라우트를 만드는 방법
·
·
·
27/98
28. Resourceful Routing
Nested Resources: Shallow Nesting - with shallow option
# in config/routes.rb
resources :posts do
resources :comments, shallow: true
end
RUBY
:shallow 옵션을 이용
이전 페이지 라우팅 선언과 동일
:index, :new, :create 액션은 부모 식별자 필요
:show, :edit, :update, :destroy 액션은 부모 식별자 없이 수행 가능
·
·
·
·
28/98
29. Resourceful Routing
Nested Resources: Multiple Shallow Nesting
# in config/routes.rb
resources :posts, shallow: true do
resources :comments
resources :quotes
resources :drafts
end
RUBY
부모 리소스에 :shallow 옵션을 지정하면
모든 중첩된 리소스들은 얕아지게 된다
·
·
29/98
30. Resourceful Routing
Nested Resources: Multiple Shallow Nesting
# in config/routes.rb
shallow do
resources :posts do
resources :comments
resources :quotes
resources :drafts
end
end
RUBY
shallow 메서드를 사용한 경우의 예제
이전 예제와 같은 라우트를 생성
·
·
30/98
31. Resourceful Routing
Nested Resources: :shallow_path option
# in config/routes.rb
scope shallow_path: "sekret" do
resources :posts do
resources :comments, shallow: true
end
end
RUBY
얕아진 라우트의 Path 앞에 · :shallow_path에 지정된 접두사를 붙인다
31/98
32. Resourceful Routing
Nested Resource: :shallow_path option Example
HTTP Verb Path Controller#Action Named Helper
GET (R) /posts/:post_id/comments(.format) comments#index post_comments
POST (C) /posts/:post_id/comments(.format) comments#create post_comments
GET (T) /posts/:post_id/comments/new(.format) comments#new new_post_comment
GET (T) /sekret/comments/:id/edit(.format) comments#edit edit_comment
GET (R) /sekret/comments(.format) comments#show comment
PATCH/PUT (U) /sekret/comments/:id(.format) comments#update comment
DELETE (D) /sekret/comments/:id(.format) comments#destroy comment
32/98
33. Resourceful Routing
Nested Resources: :shallow_prefix option
# in config/routes.rb
scope shallow_prefix: "sekret" do
resources :posts do
resources :comments, shallow: true
end
end
RUBY
얕아진 라우트의 Named · Helper 앞에 :shallow_prefix에 지정된 접두사를 붙인다
33/98
34. Resourceful Routing
Nested Resource: :shallow_prefix option Example
HTTP Verb Path Controller#Action Named Helper
GET (R) /posts/:post_id/comments(.format) comments#index post_comments
POST (C) /posts/:post_id/comments(.format) comments#create post_comments
GET (T) /posts/:post_id/comments/new(.format) comments#new new_post_comment
GET (T) /comments/:id/edit(.format) comments#edit edit_sekret_comment
GET (R) /comments(.format) comments#show sekret_comment
PATCH/PUT (U) /comments/:id(.format) comments#update sekret_comment
DELETE (D) /comments/:id(.format) comments#destroy sekret_comment
34/98
35. Resourceful Routing
Routing Concerns
# in config/routes.rb
concern :commentable do
resources :comments
end
concern :image_attachable do
resources :images, only: :index
end
RUBY
· 일반적인 라우트를 다른 리소스나 라우트 내부에서 재사용할 수 있도록 해줌
35/98
36. Resourceful Routing
Routing Concerns
# in config/routes.rb
resources :messages, concern: :commentable
# => Same as
resources :messages do
resources :comments
end
resources :posts, concerns: [:commentable, :image_attachable]
# => Same as
resources :posts do
resources :comments
resources :images, only: :index
end
RUBY
코드 중복을 · 피하고 라우트간 행동을 공유하기 위해 리소스 내부에 사용할 수 있음
36/98
37. Resourceful Routing
Routing Concerns
# in config/routes.rb
namespace :posts do
concerns :commentable
end
RUBY
Concerns는 라우트 안에 넣고자 하는 어떤 곳이든 사용할 수 있음
예) 네임스페이스 호출 내부
·
·
37/98
38. Resourceful Routing
Creating Paths and URLs from Objects
# in config/routes.rb
resources :magazines do
resources :ad
end
RUBY
<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %> ERB
Helper를 · 사용할 때, 숫자 ID 대신 인스턴스를 전달할 수 있다
38/98
39. Resourceful Routing
Creating Paths and URLs from Objects
# in config/routes.rb
resources :magazines do
resources :ad
end
RUBY
<%= link_to 'Ad details', url_for([@magazine, @ad]) %> ERB
url_for를 객체의 집합과 함께 사용 가능
주어진 객체의 집합으로, 레일스는 자동으로 어떤 라우트를 원하는지 알아낸다.
·
·
39/98
40. Resourceful Routing
Creating Paths and URLs from Objects
# in config/routes.rb
resources :magazines do
resources :ad
end
RUBY
<%= link_to 'Magazine details', @magazine) %> ERB
· 객체를 지정하는 것만으로도 링크를 생성할 수 있다.
40/98
41. Resourceful Routing
Creating Paths and URLs from Objects
# in config/routes.rb
resources :magazines do
resources :ads
end
RUBY
<%= link_to 'Magazine details', [:edit, @magazine, @ad]) %> ERB
·
배열의 첫 번째 요소로 액션 명을 지정하면 해당 액션의 링크를 생성
·
이 경우, edit_magazine_ad_path를 반환
41/98
42. Resourceful Routing
Adding More RESTful Actions
기본적으로 레스트풀 라우팅은 7개의 라우트를 만들어냄
원한다면 더 많은 라우트를 추가할 수 있다!
·
·
멤버 라우트
컬렉션 라우트
·
·
42/98
43. Resourceful Routing
Adding Member Routes
# in config/routes.rb
resources :photos do
member do
get 'preview'
end
end
# => or
resources :photos do
get 'preview', on: :member
end
RUBY
get, patch, put, post 혹은 delete 사용 가능
/photos/:id/preview URL 인식 가능하게 됨
preview_photo_url, preview_photo_path 헬퍼 사용가능하게 됨
·
·
·
43/98
44. Resourceful Routing
Adding Collection Routes
# in config/routes.rb
resources :photos do
collection do
get 'search'
end
end
# => or
resources :photos do
get 'search', on: :collection
end
RUBY
/photos/search URL 인식 가능하게 됨
search_photo_url, search_photo_path 헬퍼 사용가능하게 됨
·
·
44/98
45. Resourceful Routing
Adding Routes for Additional New Actions
# in config/routes.rb
resources :comments do
get 'preview', on: :new
end
RUBY
:on 숏컷을 이용, 부가적인 새 액션을 추가할 수 있음
get 방식 /comments/new/preview 와 같은 경로를 인식할 수 있게 해 줌
preview_new_comment_url과 preview_new_comment_path 라우트 헬퍼를 생성함
·
·
·
45/98
46. Resourceful Routing
Tip
필요한 만큼 많은 멤버 라우트 혹은 컬렉션 라우트를 추가할 수 있음
하지만 리소스플 라우트에 추가 액션을 너무 많이 추가하고 있다면?
잠시 액션 추가를 중단하고 다른 리소스를 잘못 활용하고 있는지 반문해야 할 것이라 권고
·
·
·
46/98
47. Non-Resourceful Routes
·
임의의 URL을 액션으로 라우팅하는 강력한 지원
·
일반적으로는 리소스풀 라우팅을 사용해야 하지만, 많은 곳에서는 단순한 라우팅이 적절
·
각 라우트를 개별적으로 설정
47/98
48. Non-Resourceful Routes
Bound Parameters
# in config/routes.rb
get ':controller(/:action(/:id))'
RUBY
:controller 심볼 - 응용프로그램의 컨트롤러 명에 매핑
:action 심볼 - 컨트롤러 내의 액션명에 매핑
·
·
48/98
49. Non-Resourceful Routes
Bound Parameters: Example
# in config/routes.rb
get ':controller(/:action(/:id))'
RUBY
GET /photos/show/1 REQUEST
params = { controller: 'photos', action: 'show', id: '1'} RUBY
49/98
50. Non-Resourceful Routes
Dynamic Segments
# in config/routes.rb
get ':controller/:action/:id/:user_id'
RUBY
GET /photos/show/1/2 REQUEST
params = { controller: 'photos', action: 'show', id: '1', user_id: '2'} RUBY
· 원하는 만큼 많은 동적 세그먼트를 설정할 수 있음
50/98
51. Non-Resourceful Routes
Dynamic Segments with Namespace or Module
# in config/routes.rb
get ':controller(/:action(/:id/))', controller: /admin/[^/]+/
RUBY
:controller 세그먼트와 함께 :namespace 혹은 :module을 사용하고 싶을 경우
필요로 하는 네임스페이스와 일치하는 제약을 :controller 상에 사용해야 한다.
·
·
51/98
52. Non-Resourceful Routes
Dynamic Segments with dots(.)
# in config/routes.rb
get ':controller(/:action(/:id/))', id: /[^/]+/
RUBY
기본적으로 동적 세그먼트는 구두점(.)을 받아들이지 않음
구두점은 형식화된 라우트를 위한 구분자로 사용되기 때문
만약 동적 세그먼트 안에 구두점을 사용할 필요가 있다면 오버라이드 제약을 추가
예) id: /[^/]+/ => 슬래시(/) 이외의 모든 것을 :id 세그먼트에 허용함
·
·
·
·
52/98
53. Non-Resourceful Routes
Static Segments
# in config/routes.rb
get ':controller/:action/:id/with_user/:user_id'
RUBY
GET /photos/show/1/with_user/2 REQUEST
params = { controller: 'photos', action: 'show', id: '1', user_id: '2'} RUBY
· 세그먼트의 앞에 콜론을 추가하지 않으면 정적 세그먼트
53/98
54. Non-Resourceful Routes
The Query String
# in config/routes.rb
get ':controller/:action/:id'
RUBY
GET /photos/show/1?user_id=2 REQUEST
params = { controller: 'photos', action: 'show', id: '1', user_id: '2'} RUBY
·
params는 질의 문자열로부터 들어온 모든 매개변수도 함께 포함한다.
·
이 경우, params에는 질의 문자로부터 들어온 user_id 값도 함께 포함하여
PhotosController의 show 액션으로 보내진다
54/98
55. Non-Resourceful Routes
Defining Default
# in config/routes.rb
get 'photos/:id', to: 'photos#show'
RUBY
GET /photos/12 REQUEST
params = { controller: 'photos', action: 'show', id: '12' } RUBY
·
라우트에서 :controller와 :action을 반드시 명시적으로 사용할 필요는 없음
·
이 경우, 레일스는 PhotosController의 show 액션으로 라우트한다.
55/98
56. Non-Resourceful Routes
Defining Default: Using :default
# in config/routes.rb
get 'photos/:id', to: 'photos#show', defaults: { format: 'jpg'}
RUBY
GET /photos/12 REQUEST
params = { controller: 'photos', action: 'show', id: '12', format: 'jpg' } RUBY
:defaults · 옵션 해시를 사용, 라우트에 기본값을 제공할 수 있음
56/98
57. Non-Resourceful Routes
Named Routes: Using :as
# in config/routes.rb
get 'exit', to: 'session#destroy', as: :logout
RUBY
logout_path, logout_url 헬퍼를 생성
logout_path는 /exit를 반환
·
·
57/98
58. Non-Resourceful Routes
Named Routes: Using :as
# in config/routes.rb
get ':username', to: 'users#show', as: :user
RUBY
GET /bob REQUEST
params = { controller: 'users', action: 'show', username: 'bob' } RUBY
58/98
59. Non-Resourceful Routes
HTTP Verb Constraint
# in config/routes.rb
match 'photos', to: 'photos#show', via: :get
match 'posts', to: 'posts#show', via: [:get, :post] # 한꺼번에 여러 메서드를 지정
match 'ads', to: 'ads#show', via: :all # 모든 메서드를 매칭
RUBY
특정 Verb로 라우트를 제한 : get, post, put, delete 사용
match 메서드를 :via 옵션과 함께 사용
GET과 POST를 단일 액션에 라우팅하는 것은 보안 문제가 있다
합당한 이유가 있는 것이 아니라면 via: :all을 이용한 라우트는 피해야 한다
·
·
·
·
59/98
60. Non-Resourceful Routes
Segment Constraint: Using :constraints option
RUBY
# in config/routes.rb
get 'photos/:id', to: 'photos#show', constraints: { id: /[A-Z]d{5}/ }
# Will route /photos/A12345
# Will not route /photos/893
get 'photos/:id', to: 'photos#show', id: /[A-Z]d{5}/ # Same as above (Short Style)
동적 세그먼트를 위한 형식을 · 강제 -> :constraints 옵션 사용
60/98
61. Non-Resourceful Routes
Segment Constraint: Anchors can't be used in :constraints option
# in config/routes.rb
get '/:id', to: 'posts#show', constraints: {id: /^d/ }
# this route will not work
RUBY
:constraints에는 정규 표현식을 사용
Anchor($, A, Z, z, G, b, B 등)는 사용할 수 없음
·
·
61/98
62. Non-Resourceful Routes
Segment Constraint: Example
# in config/routes.rb
get '/:id', to: 'posts#show', constraints: { id: /d.+/ }
get '/:username', to: 'users#show'
# => always begin with a number like '/1-hello-world'
# => never begin with a number like '/david'
RUBY
숫자로 시작하는 라우트를 posts#show로 라우트하고
숫자로 시작하지 않는 라우트는 users#show로 라우트한다
·
·
62/98
63. Non-Resourceful Routes
Request-Based Constraints
# in config/routes.rb
get 'photos', constraints: { subdomain: 'admin' }
RUBY
# in config/routes.rb
# Block Style
namespace :admin do
constraints subdomain: 'admin' do
resources: :photos
end
end
RUBY
String을 반환하는 Request 객체상의 메서드에 기반한 라우트를 제한할 수도 있다.
세그먼트 제약을 명시하는 것과 같은 방식으로 요청기반의 제약을 명시할 수 있다.
·
·
63/98
64. Non-Resourceful Routes
Advanced Constraints
# in config/routes.rb
class BlacklistConstraint
def initialize
@ips = Blacklist.retrieve_ips
end
def matches?(request)
@ips.include?(request.remote_ip)
end
end
TwitterClone::Application.routes.draw do
get '*path', to: 'blacklist#index',
constraints: BlacklistConstraints.new
end
RUBY
matches? 에 응답하는 객체를 제공, 더 고급스런 제약을 사용할 수 있다.
예제 코드는 블랙리스트상에 있는 모든 사용자의 요청을 BlacklistController에 라우트하는 코드
·
·
64/98
65. Non-Resourceful Routes
Advanced Constraints: Using lambda
# in config/routes.rb
TwitterClone::Application.routes.draw do
get '*path', to: 'blacklist#index',
constraints: lambda { |request| Blacklist.retrieve_ips.include?(request.remote_ip) }
end
RUBY
constraints는 람다로 명시할 수도 있다.
matches? 메서드와 lambda 모두 인수로 request를 가져온다.
·
·
65/98
66. Non-Resourceful Routes
Route Globbing and Wildcard Segments
# in config/routes.rb
get 'photos/*other', to: 'photos#unknown'
# params[:controller] == 'photos', params[:action] == 'unknown'
# /photos/12 => params[:other] == 12
# /photos/long/path/to/12 => params[:other] == 'long/path/to/12'
RUBY
라우트의 잔여 부분 전체에 매칭되는 특정 매개변수를 지정할 수 있다.
와일드카드(*) 세그먼트
·
·
66/98
67. Non-Resourceful Routes
Route Globbing and Wildcard Segments
RUBY
# in config/routes.rb
get 'books/*section/:title', to: 'books#show'
# params[:controller] == 'books', params[:title] == 'show'
# /books/some/section/last-words-a-memoir => params[:section] == 'some/section', params[:title] == 'last-words-a-memoir'
· 와일드카드 세그먼트는 라우트의 어떤 곳에서도 사용될 수 있음.
67/98
68. Non-Resourceful Routes
Multi Wildcard Segments
# in config/routes.rb
get '*a/foo/*b', to: 'test#index'
# /pre/fix/foo/suf/fix => params[:a] == 'pre/fix', params[:b] == 'suf/fix'
RUBY
라우트는 하나 이상의 와일드 카드 세그먼트를 가질 수 있음.
matcher는 직관적 방식으로 세그먼트를 매개변수에 할당.
·
·
68/98
69. Non-Resourceful Routes
Redirection
# in config/routes.rb
get '/stories', to: redirect('/posts')
# '/stories' => will be redirected to '/posts'
RUBY
redirect · 헬퍼를 사용, 다른 경로로 리다이렉트 할 수 있다.
69/98
70. Non-Resourceful Routes
Redirection : Reusing dynamic segment
# in config/routes.rb
get '/stories/:name', to: redirect('/posts/%{name}')
RUBY
· 동적 세그먼트를 재사용, 경로에 리다이렉트할 곳을 매칭
70/98
71. Non-Resourceful Routes
Redirection : params and request
# in config/routes.rb
get '/stories/:name', to: redirect { |params, req| "/posts/#{params[:name].pluralize}" }
get '/stories', to: redirect { |p, req| "/posts/#{req.subdomain}" }
RUBY
리다이렉트에 params와 request 객체를 수신하는 블록을 제공할 수도 있음
본 리다이렉션은 301 "Moved Permanently" 리다이렉트임을 주지
·
·
71/98
72. Non-Resourceful Routes
Routing to Rack Applications
# in config/routes.rb
match '/application.js', to: Sprockets, via: :all
RUBY
엔드포인트로서 특정 Rack · application을 지정할 수 있음
72/98
73. Non-Resourceful Routes
root
# in config/routes.rb
root to: 'pages#main'
root 'pages#main' # shortcut for the above
RUBY
root 라우트는 파일의 맨 처음에 둘 것을 권고
root 라우트는 GET 요청만 액션으로 라우트한다.
·
·
73/98
74. Non-Resourceful Routes
root in namespace or scope
# in config/routes.rb
namespace :admin do
root to: 'admin@index'
end
root to: 'home#index'
RUBY
namespace · 혹은 scope 내에 root를 사용할 수도 있다
74/98
75. Non-Resourceful Routes
Unicode Character Unicode character routes
# in config/routes.rb
get '안녕하세요', to: 'welcome#index'
get 'こんにちは', to: 'welcome#index'
get '好', to: 'welcome#index'
RUBY
· 직접적으로 유니코드 캐릭터 라우트를 지정할 수 있음
75/98
76. Customizing Resourceful Routes
Specifying a Controller to Use
# in config/routes.rb
resources :photos, controller: 'images'
RUBY
본 라우트는 /photos로 시작하는 유입 경로를 인식
ImagesController로 라우트
·
·
76/98
77. Customizing Resourceful Routes
Specifying a Controller to Use
HTTP Verb Path Controller#Action Named Helper
GET (R) /photos images#index photos_path
GET (T) /photos/new images#new new_photo_path
POST (C) /photos images#create photos_path
GET (R) /photos/:id images#show photo_path(:id)
GET (T) /photos/:id/edit images#edit photo_path(:id)
PATCH/PUT (U) /photos/:id images#update photo_path(:id)
DELETE (D) /photos/:id images#destroy photo_path(:id)
77/98
78. Customizing Resourceful Routes
Specifying a Controller to Use: with Namespace
# in config/routes.rb
resources :user_permissions, controller: 'admin/user_permissions' # Good! Do!
resources :user_permissions, controller: 'Admin::UserPermissions' # Bad! Don't!
RUBY
네임스페이스 컨트롤러를 사용할 경우, 디렉터리 표기를 사용
루비 상수 표기법으로 표기하면 라우팅 문제와 경고를 초래
·
·
78/98
79. Customizing Resourceful Routes
Specifying Constraints
# in config/routes.rb
resources :photos, constraints: { id: /[A-Z][A-Z][0-9]+/ }
# will route /photos/AB0123
# will not route /photos/1
RUBY
암시적 id에 필요한 형식 지정을 위해 :contraints 옵션을 사용
제공된 정규표현식에 일치하지 않는 :id 매개변수를 제한
·
·
79/98
80. Customizing Resourceful Routes
Specifying Constraints : Block form
# in config/routes.rb
constraints(id: /[A-Z][A-Z][0-9]+/) do
resources :photos
resources :accounts
end
RUBY
· 블록 형식을 사용, 여러 라우트에 단일 제약을 적용할 수 있음
80/98
81. Customizing Resourceful Routes
Overriding the Named Helpers
# in config/routes.rb
resources :photos, as: 'images'
RUBY
/photos로 시작하는 유입경로를 인식, PhotosController로 라우트
:as 옵션의 값을 이용하여 헬퍼의 이름을 작명
·
·
81/98
82. Customizing Resourceful Routes
Overriding the Named Helpers
HTTP Verb Path Controller#Action Named Helper
GET (R) /photos photos#index images_path
GET (T) /photos/new photos#new new_image_path
POST (C) /photos photos#create images_path
GET (R) /photos/:id photos#show image_path(:id)
GET (T) /photos/:id/edit photos#edit image_path(:id)
PATCH/PUT (U) /photos/:id photos#update image_path(:id)
DELETE (D) /photos/:id photos#destroy image_path(:id)
82/98
83. Customizing Resourceful Routes
Overriding the new and edit Segments
# in config/routes.rb
resources :photos, path_names: { new: 'make', edit: 'change' }
# will route /photos/make to photos#new
# will route /photos/1/change to photos#edit with params[:id] == 1
RUBY
실제 액션 명은 변경되지 않음
두 경로는 여전히 new와 edit 액션으로 라우트될 것
·
·
83/98
84. Customizing Resourceful Routes
Overriding the new and edit Segments with scope
# in config/routes.rb
scope path_names: { new: 'make' } do
resources :photos
resources :articles
end
RUBY
scope · 범위 내에 있는 모든 라우트의 new 액션명을 make로 대치
84/98
85. Customizing Resourceful Routes
Prefixing the Named Route Helper
# in config/routes.rb
scope 'admin' do
resources :photos, as: 'admin_photos'
end
resources :photos
RUBY
라우트와 경로 스코프간의 이름 충돌을 방지하기 위해 :as 옵션을 사용
'admin' scope 내의 photos는 admin_photos_path, new_admin_photo_path 등의 라우트 헬퍼를 제공하게 될것
·
·
85/98
86. Customizing Resourceful Routes
Prefixing the Named Route Helper
# in config/routes.rb
scope 'admin', as: 'admin' do
resources :photos, :accounts
end
resources :photos, :accounts
RUBY
스코프 내 여러 리소스의 라우트 헬퍼 집합에 접두어를 붙이려면
scope와 함께 :as 옵션을 사용
·
·
86/98
87. Customizing Resourceful Routes
Prefixing Routes with a Named Parameter
# in config/routes.rb
scope ':username' do
resources :posts
end
# will route /bob/posts/1 to posts#show with params[:username] == 'bob'
RUBY
· 명명된 파라미터로의 라우트에 접두사를 붙이는 방법
87/98
88. Customizing Resourceful Routes
Restricting the Routes Created
# in config/routes.rb
resources :photos, only: [:index, :show]
resources :notes, except: :destroy
RUBY
레일스가 기본으로 생성하는 일곱 개의 레스트풀 라우트 기본 액션을 조정할 수 있음
:only 옵션 - 지정된 액션만 생성, 나머지는 생성하지 않음
:only와 :except를 사용하여 실제로 필요한 라우트만 생성하면 메모리 사용량을 줄이고 라우팅 프로세스의 속도를 높일 수
있다.
·
·
·
88/98
89. Customizing Resourceful Routes
Tralated Paths
# in config/routes.rb
scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do
resources :categories, path: 'Kategorien'
end
RUBY
scope를 · 사용, 리소스에 의해 생성된 경로명을 변경할 수 있음
89/98
90. Customizing Resourceful Routes
Overriding the Named Helpers
HTTP Verb Path Controller#Action Named Helper
GET (R) /kategorien categories#index categories_path
GET (T) /kategorien/neu categories#new new_categories_path
POST (C) /kategorien categories#create categories_path
GET (R) /kategorien/:id categories#show category_path(:id)
GET (T) /kategorien/:id/bearbeiten categories#edit edit_category_path(:id)
PATCH/PUT (U) /kategorien/:id categories#update category_path(:id)
DELETE (D) /kategorien/:id categories#destroy category_path(:id)
90/98
91. Customizing Resourceful Routes
Overriding the Singular Form
# in config/initializers/inflections.rb
ActiveSupport::Inflector.inflections do |inflect|
inflect.irregular 'tooth', 'teeth'
end
RUBY
리소스의 단수 형식을 정의하기 위해 ActiveSupport::· Inflector에 부가 규칙을 더함
91/98
92. Customizing Resourceful Routes
Using :as in Nested Resources
# in config/routes.rb
resources :magazines do
resources :ads, as: 'periodical_ads'
end
RUBY
:as 옵션은 중첩 라우트 헬퍼를 위해 자동 생성된 이름을 오버라이드함.
본 예제에서는 magazine_periodical_ads_url과 edit_magazine_periodical_ad_path 같은 라우팅 헬퍼를 생성.
·
·
92/98
93. Customizing Resourceful Routes
Inspecting and Testing Routes
$ rake routes # all routes
$ rake routes CONTROLLER=posts # routes for PostsController
SH
브라우저에서: http://localhost:3000/rails/info/routes
터미널에서: rake routes를 이용
특정 컨트롤러로 매핑되는 라우트 목록으로 한정하려면 CONTROLLER 환경변수를 이용
·
·
·
93/98
94. Customizing Resourceful Routes
Testing Routes
라우트는 테스팅 전략에 포함되어야 한다고 권고
테스트를 간단하게 할 수 있는 세 가지 내장 assertion을 제공
·
·
assert_generates
assert_recognizes
assert_routing
·
·
·
94/98
95. Customizing Resourceful Routes
Testing Routes: assert_generates
# in test/integration/test_routes_test.rb
assert_generates '/photos/1', { controller: 'photos', action: 'show', id: '1' }
assert_generates '/about', { controller: 'pages', action: 'about' }
SH
옵션 셋이 특정 경로를 생성하고 기본 라우트 혹은 · 커스텀 라우트와 함께 사용될 수 있음을 assert 한다
95/98
96. Customizing Resourceful Routes
Testing Routes: assert_recognizes
SH
# in test/integration/test_routes_test.rb
assert_recognizes( { controller: 'photos', action: 'show', id: '1'}, '/photos/1')
assert_recognizes( { controller: 'photos', action: 'create' }, { path: '/photos', method: :post } ) # specific HTTP verb
assert_generates의 반대
주어진 경로가 응용프로그램의 특정 지점을 인식하고 라우트함을 assert
·
·
96/98
97. Customizing Resourceful Routes
Testing Routes: assert_routing
# in test/integration/test_routes_test.rb
assert_routing({ path: 'photos', method: :post }, { controller: 'photos', action: 'create' })
SH
assert_generates + assert_recognizes
경로가 옵션을 생성하는 것, 옵션이 경로를 생성하는 것을 함께 테스트
·
·
97/98
98. Thank you
Thanks to:
RoRLab Members
Naver D2
Google (Slide Template)
·
·
·