98
Rails Routing from the Outside In RoR Lab BiWeekly Lecture 남승균 - RoR Lab

Rails routing from the outside in

Embed Size (px)

DESCRIPTION

RoR Lab Lecture 67~69 Rails Routing from Outside In

Citation preview

Page 1: Rails routing from the outside in

Rails Routing from the Outside InRoR Lab BiWeekly Lecture

남승균 - RoR Lab

Page 2: Rails routing from the outside in

Rails RouterPurpose

URL을 인식, 파라미터와 함께 컨트롤러의 액션에 전달경로(path)와 URL을 생성, 뷰에 하드 코딩할 필요를 없애줌config/routes.rb

···

2/98

Page 3: Rails routing from the outside in

Rails RouterConcept: How Rails Router Works

3/98

Page 4: Rails routing from the outside in

Rails RouterExample: Basic Routing

4/98

Page 5: Rails routing from the outside in

Generating Paths and URLs from CodeBasic Sample Code

# in config/routes.rbget '/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

Page 6: Rails routing from the outside in

Resourceful RoutingThe Rails Default

# in config/routes.rbresources :photos

RUBY

한 줄의 코드로 리소스 라우팅을 위한 일반적인 라우트를 빠르게 선언index, show, new, edit, create, update, destroy (7개)

··

6/98

Page 7: Rails routing from the outside in

Resourceful RoutingCRUD 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

Page 8: Rails routing from the outside in

Resourceful RoutingCRUD in Rails: Example

# in config/routes.rbresources :photos

RUBY

8/98

Page 9: Rails routing from the outside in

Resourceful RoutingCRUD 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

Page 10: Rails routing from the outside in

Resourceful RoutingCRUD 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

Page 11: Rails routing from the outside in

Resourceful RoutingPath 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

Page 12: Rails routing from the outside in

Resourceful RoutingDefining Multiple Resources at the Same Time

# in config/routes.rbresources :photosresources :booksresources :videos

RUBY

# in config/routes.rb# Defining Multiple Resource at the Same Timeresources :photos, :books, :videos

RUBY

12/98

Page 13: Rails routing from the outside in

Resourceful RoutingSingular Resources

# in config/routes.rbresource :geocoder

RUBY

id를 참조하지 않고 조회하는 자원의 경우index, show, new, edit, create, update, destroy (6개)복수형 컨트롤러에 매핑됨: 단수형과 복수형 리소스를 함께 사용하고자 할 수 있기 때문

···

13/98

Page 14: Rails routing from the outside in

Resourceful RoutingSingular 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

Page 15: Rails routing from the outside in

Resourceful Routing단수형, 복수형 리소스 동시에 사용하기

# in config/routes.rbresource :photoresources :photos

RUBY

동일 컨트롤러(PhotosController)에 매핑되는 단수형과 복수형 라우트를 동시에 생성·

15/98

Page 16: Rails routing from the outside in

Resourceful RoutingPath 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

Page 17: Rails routing from the outside in

Resourceful RoutingNamespace and Routing

# in config/routes.rbnamespace :admin do resources :posts, :commentsend

RUBY

# in app/controllers/admin/posts_controller.rbclass Admin::PostsController < ApplicationController # class codesend

RUBY

컨트롤러의 묶음을 네임스페이스 아래 정리하고자 할 때예: admin 관련 컨트롤러들을 Admin:: 네임스페이스 아래 묶음

··

17/98

Page 18: Rails routing from the outside in

Resourceful RoutingNamespaced 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

Page 19: Rails routing from the outside in

Resourceful RoutingNamespace and Routing: Using scope module

# in config/routes.rbscope module: 'admin' do resources :posts, :commentsend

RUBY

# in config/routes.rbresources :posts, module: 'admin'

RUBY

특정 모듈 접두사가 붙은 컨트롤러를 접두사 없이 라우트하고 싶을 때예: Admin:: 접두사가 붙은 모듈을 접두사(/admin) 없이 라우트

··

19/98

Page 20: Rails routing from the outside in

Resourceful RoutingNamespace and Routing: Using scope

# in config/routes.rbscope 'admin' do resources :posts, :commentsend

RUBY

# in config/routes.rbresources :posts, path: '/admin/posts'

RUBY

특정 모듈 접두사가 없는 컨트롤러를 접두사를 붙여 라우트하고 싶을 때예: 모듈 접두사 없는 컨트롤러 PostsController를 접두사를 붙여 /admin/posts로 라우트

··

20/98

Page 21: Rails routing from the outside in

Resourceful RoutingNamespaced 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

Page 22: Rails routing from the outside in

잠깐만... 놓치고 간 내용라우트는 선언 순서가 중요

# in config/routes.rbget '/patients/:id', to: 'patients#show', as: 'patient'get '/patients/test'

RUBY

# in config/routes.rbget '/patients/test'get '/patients/:id', to: 'patients#show', as: 'patient'

RUBY

상단 routes.rb 코드로는 PatientsController의 test 액션을 실행할 방법이 없음하단 routes.rb 코드처럼 작성해야 PatientsController의 test 액션에 도달 가능routes.rb 파일 작성시 순서가 중요함

·

·

·

22/98

Page 23: Rails routing from the outside in

Resourceful RoutingNested Resources

class Magazine < ActiveRecord::Base has_many :adsend

class Ad < ActiveRecord::Base belongs_to :magazineend

RUBY

# in config/routes.rbresources :magazines do resources :adsend

RUBY

논리적으로 자식인 리소스를 중첩하는 방법중첩 라우트는 라우팅의 관계를 캡쳐할 수 있게 해 준다본 라우트는 magazines를 위한 라우트이며 동시에 ads를 AdsController에 라우트ad의 URL은 magazine을 필요로 함

·

·

·

·

23/98

Page 24: Rails routing from the outside in

Resourceful RoutingNested 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

Page 25: Rails routing from the outside in

Resourceful RoutingLimits to Nesting

# in config/routes.rbresources :publishers do resources :magazines do resources :photos endend

RUBY

원한다면, 다른 중첩된 리소스 안에 리소스를 중첩할 수 있다깊게 중첩된 라우트는 급속도로 복잡해진다

··

25/98

Page 26: Rails routing from the outside in

Resourceful RoutingLimits 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

Page 27: Rails routing from the outside in

Resourceful RoutingNested Resources: Shallow Nesting

# in config/routes.rb

resources :posts do resources :comments, only: [:index, :new, :create]endresources :comments, only: [:show, :edit, :update, :destroy]

RUBY

깊은 중첩을 피하기 위해, 부모 아래 범주화된 액션의 컬렉션을 생성멤버 액션을 중첩하지 않고 계층의 의미를 갖게 함최소한의 정보로 고유하게 리소스를 식별하는 라우트를 만드는 방법

·

·

·

27/98

Page 28: Rails routing from the outside in

Resourceful RoutingNested Resources: Shallow Nesting - with shallow option

# in config/routes.rb

resources :posts do resources :comments, shallow: trueend

RUBY

:shallow 옵션을 이용이전 페이지 라우팅 선언과 동일:index, :new, :create 액션은 부모 식별자 필요:show, :edit, :update, :destroy 액션은 부모 식별자 없이 수행 가능

·

·

·

·

28/98

Page 29: Rails routing from the outside in

Resourceful RoutingNested Resources: Multiple Shallow Nesting

# in config/routes.rb

resources :posts, shallow: true do resources :comments resources :quotes resources :draftsend

RUBY

부모 리소스에 :shallow 옵션을 지정하면모든 중첩된 리소스들은 얕아지게 된다

··

29/98

Page 30: Rails routing from the outside in

Resourceful RoutingNested Resources: Multiple Shallow Nesting

# in config/routes.rb

shallow do resources :posts do resources :comments resources :quotes resources :drafts endend

RUBY

shallow 메서드를 사용한 경우의 예제이전 예제와 같은 라우트를 생성

··

30/98

Page 31: Rails routing from the outside in

Resourceful RoutingNested Resources: :shallow_path option

# in config/routes.rb

scope shallow_path: "sekret" do resources :posts do resources :comments, shallow: true endend

RUBY

얕아진 라우트의 Path 앞에 :shallow_path에 지정된 접두사를 붙인다·

31/98

Page 32: Rails routing from the outside in

Resourceful RoutingNested 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

Page 33: Rails routing from the outside in

Resourceful RoutingNested Resources: :shallow_prefix option

# in config/routes.rb

scope shallow_prefix: "sekret" do resources :posts do resources :comments, shallow: true endend

RUBY

얕아진 라우트의 Named Helper 앞에 :shallow_prefix에 지정된 접두사를 붙인다·

33/98

Page 34: Rails routing from the outside in

Resourceful RoutingNested 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

Page 35: Rails routing from the outside in

Resourceful RoutingRouting Concerns

# in config/routes.rb

concern :commentable do resources :commentsend

concern :image_attachable do resources :images, only: :indexend

RUBY

일반적인 라우트를 다른 리소스나 라우트 내부에서 재사용할 수 있도록 해줌·

35/98

Page 36: Rails routing from the outside in

Resourceful RoutingRouting Concerns

# in config/routes.rbresources :messages, concern: :commentable# => Same asresources :messages do resources :commentsend

resources :posts, concerns: [:commentable, :image_attachable]# => Same asresources :posts do resources :comments resources :images, only: :indexend

RUBY

코드 중복을 피하고 라우트간 행동을 공유하기 위해 리소스 내부에 사용할 수 있음·

36/98

Page 37: Rails routing from the outside in

Resourceful RoutingRouting Concerns

# in config/routes.rb

namespace :posts do concerns :commentableend

RUBY

Concerns는 라우트 안에 넣고자 하는 어떤 곳이든 사용할 수 있음예) 네임스페이스 호출 내부

··

37/98

Page 38: Rails routing from the outside in

Resourceful RoutingCreating Paths and URLs from Objects

# in config/routes.rb

resources :magazines do resources :adend

RUBY

<%= link_to 'Ad details', magazine_ad_path(@magazine, @ad) %> ERB

Helper를 사용할 때, 숫자 ID 대신 인스턴스를 전달할 수 있다·

38/98

Page 39: Rails routing from the outside in

Resourceful RoutingCreating Paths and URLs from Objects

# in config/routes.rb

resources :magazines do resources :adend

RUBY

<%= link_to 'Ad details', url_for([@magazine, @ad]) %> ERB

url_for를 객체의 집합과 함께 사용 가능주어진 객체의 집합으로, 레일스는 자동으로 어떤 라우트를 원하는지 알아낸다.

·

·

39/98

Page 40: Rails routing from the outside in

Resourceful RoutingCreating Paths and URLs from Objects

# in config/routes.rb

resources :magazines do resources :adend

RUBY

<%= link_to 'Magazine details', @magazine) %> ERB

객체를 지정하는 것만으로도 링크를 생성할 수 있다.·

40/98

Page 41: Rails routing from the outside in

Resourceful RoutingCreating Paths and URLs from Objects

# in config/routes.rb

resources :magazines do resources :adsend

RUBY

<%= link_to 'Magazine details', [:edit, @magazine, @ad]) %> ERB

배열의 첫 번째 요소로 액션 명을 지정하면 해당 액션의 링크를 생성이 경우, edit_magazine_ad_path를 반환

·

·

41/98

Page 42: Rails routing from the outside in

Resourceful RoutingAdding More RESTful Actions

기본적으로 레스트풀 라우팅은 7개의 라우트를 만들어냄원한다면 더 많은 라우트를 추가할 수 있다!

··

멤버 라우트컬렉션 라우트

··

42/98

Page 43: Rails routing from the outside in

Resourceful RoutingAdding Member Routes

# in config/routes.rb

resources :photos do member do get 'preview' endend

# => or

resources :photos do get 'preview', on: :memberend

RUBY

get, patch, put, post 혹은 delete 사용 가능/photos/:id/preview URL 인식 가능하게 됨preview_photo_url, preview_photo_path 헬퍼 사용가능하게 됨

·

·

·

43/98

Page 44: Rails routing from the outside in

Resourceful RoutingAdding Collection Routes

# in config/routes.rb

resources :photos do collection do get 'search' endend

# => or

resources :photos do get 'search', on: :collectionend

RUBY

/photos/search URL 인식 가능하게 됨search_photo_url, search_photo_path 헬퍼 사용가능하게 됨

·

·

44/98

Page 45: Rails routing from the outside in

Resourceful RoutingAdding Routes for Additional New Actions

# in config/routes.rb

resources :comments do get 'preview', on: :newend

RUBY

:on 숏컷을 이용, 부가적인 새 액션을 추가할 수 있음get 방식 /comments/new/preview 와 같은 경로를 인식할 수 있게 해 줌preview_new_comment_url과 preview_new_comment_path 라우트 헬퍼를 생성함

·

·

·

45/98

Page 46: Rails routing from the outside in

Resourceful RoutingTip

필요한 만큼 많은 멤버 라우트 혹은 컬렉션 라우트를 추가할 수 있음하지만 리소스플 라우트에 추가 액션을 너무 많이 추가하고 있다면?잠시 액션 추가를 중단하고 다른 리소스를 잘못 활용하고 있는지 반문해야 할 것이라 권고

···

46/98

Page 47: Rails routing from the outside in

Non-Resourceful Routes임의의 URL을 액션으로 라우팅하는 강력한 지원일반적으로는 리소스풀 라우팅을 사용해야 하지만, 많은 곳에서는 단순한 라우팅이 적절각 라우트를 개별적으로 설정

···

47/98

Page 48: Rails routing from the outside in

Non-Resourceful RoutesBound Parameters

# in config/routes.rb

get ':controller(/:action(/:id))'

RUBY

:controller 심볼 - 응용프로그램의 컨트롤러 명에 매핑:action 심볼 - 컨트롤러 내의 액션명에 매핑

··

48/98

Page 49: Rails routing from the outside in

Non-Resourceful RoutesBound 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

Page 50: Rails routing from the outside in

Non-Resourceful RoutesDynamic 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

Page 51: Rails routing from the outside in

Non-Resourceful RoutesDynamic Segments with Namespace or Module

# in config/routes.rb

get ':controller(/:action(/:id/))', controller: /admin\/[^/\]+/

RUBY

:controller 세그먼트와 함께 :namespace 혹은 :module을 사용하고 싶을 경우필요로 하는 네임스페이스와 일치하는 제약을 :controller 상에 사용해야 한다.

··

51/98

Page 52: Rails routing from the outside in

Non-Resourceful RoutesDynamic Segments with dots(.)

# in config/routes.rb

get ':controller(/:action(/:id/))', id: /[^/\]+/

RUBY

기본적으로 동적 세그먼트는 구두점(.)을 받아들이지 않음구두점은 형식화된 라우트를 위한 구분자로 사용되기 때문만약 동적 세그먼트 안에 구두점을 사용할 필요가 있다면 오버라이드 제약을 추가예) id: /[^/\]+/ => 슬래시(/) 이외의 모든 것을 :id 세그먼트에 허용함

····

52/98

Page 53: Rails routing from the outside in

Non-Resourceful RoutesStatic 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

Page 54: Rails routing from the outside in

Non-Resourceful RoutesThe 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

Page 55: Rails routing from the outside in

Non-Resourceful RoutesDefining 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

Page 56: Rails routing from the outside in

Non-Resourceful RoutesDefining 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

Page 57: Rails routing from the outside in

Non-Resourceful RoutesNamed Routes: Using :as

# in config/routes.rb

get 'exit', to: 'session#destroy', as: :logout

RUBY

logout_path, logout_url 헬퍼를 생성logout_path는 /exit를 반환

··

57/98

Page 58: Rails routing from the outside in

Non-Resourceful RoutesNamed 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

Page 59: Rails routing from the outside in

Non-Resourceful RoutesHTTP 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

Page 60: Rails routing from the outside in

Non-Resourceful RoutesSegment Constraint: Using :constraints option

# 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)

RUBY

동적 세그먼트를 위한 형식을 강제 -> :constraints 옵션 사용·

60/98

Page 61: Rails routing from the outside in

Non-Resourceful RoutesSegment 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

Page 62: Rails routing from the outside in

Non-Resourceful RoutesSegment 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

Page 63: Rails routing from the outside in

Non-Resourceful RoutesRequest-Based Constraints

# in config/routes.rb

get 'photos', constraints: { subdomain: 'admin' }

RUBY

# in config/routes.rb

# Block Stylenamespace :admin do constraints subdomain: 'admin' do resources: :photos endend

RUBY

String을 반환하는 Request 객체상의 메서드에 기반한 라우트를 제한할 수도 있다.

세그먼트 제약을 명시하는 것과 같은 방식으로 요청기반의 제약을 명시할 수 있다.

·

·

63/98

Page 64: Rails routing from the outside in

Non-Resourceful RoutesAdvanced Constraints

# in config/routes.rb

class BlacklistConstraint def initialize @ips = Blacklist.retrieve_ips end

def matches?(request) @ips.include?(request.remote_ip) endend

TwitterClone::Application.routes.draw do get '*path', to: 'blacklist#index', constraints: BlacklistConstraints.newend

RUBY

matches? 에 응답하는 객체를 제공, 더 고급스런 제약을 사용할 수 있다.

예제 코드는 블랙리스트상에 있는 모든 사용자의 요청을 BlacklistController에 라우트하는 코드·

·

64/98

Page 65: Rails routing from the outside in

Non-Resourceful RoutesAdvanced 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

Page 66: Rails routing from the outside in

Non-Resourceful RoutesRoute 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

Page 67: Rails routing from the outside in

Non-Resourceful RoutesRoute Globbing and Wildcard Segments

# 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'

RUBY

와일드카드 세그먼트는 라우트의 어떤 곳에서도 사용될 수 있음.·

67/98

Page 68: Rails routing from the outside in

Non-Resourceful RoutesMulti 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

Page 69: Rails routing from the outside in

Non-Resourceful RoutesRedirection

# in config/routes.rb

get '/stories', to: redirect('/posts')

# '/stories' => will be redirected to '/posts'

RUBY

redirect 헬퍼를 사용, 다른 경로로 리다이렉트 할 수 있다.·

69/98

Page 70: Rails routing from the outside in

Non-Resourceful RoutesRedirection : Reusing dynamic segment

# in config/routes.rb

get '/stories/:name', to: redirect('/posts/%{name}')

RUBY

동적 세그먼트를 재사용, 경로에 리다이렉트할 곳을 매칭·

70/98

Page 71: Rails routing from the outside in

Non-Resourceful RoutesRedirection : 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

Page 72: Rails routing from the outside in

Non-Resourceful RoutesRouting to Rack Applications

# in config/routes.rb

match '/application.js', to: Sprockets, via: :all

RUBY

엔드포인트로서 특정 Rack application을 지정할 수 있음·

72/98

Page 73: Rails routing from the outside in

Non-Resourceful Routesroot

# in config/routes.rb

root to: 'pages#main'root 'pages#main' # shortcut for the above

RUBY

root 라우트는 파일의 맨 처음에 둘 것을 권고root 라우트는 GET 요청만 액션으로 라우트한다.

·

·

73/98

Page 74: Rails routing from the outside in

Non-Resourceful Routesroot 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

Page 75: Rails routing from the outside in

Non-Resourceful RoutesUnicode Character Unicode character routes

# in config/routes.rb

get '안녕하세요', to: 'welcome#index'get 'こんにちは', to: 'welcome#index'get '�好', to: 'welcome#index'

RUBY

직접적으로 유니코드 캐릭터 라우트를 지정할 수 있음·

75/98

Page 76: Rails routing from the outside in

Customizing Resourceful RoutesSpecifying a Controller to Use

# in config/routes.rb

resources :photos, controller: 'images'

RUBY

본 라우트는 /photos로 시작하는 유입 경로를 인식ImagesController로 라우트

·

·

76/98

Page 77: Rails routing from the outside in

Customizing Resourceful RoutesSpecifying 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

Page 78: Rails routing from the outside in

Customizing Resourceful RoutesSpecifying 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

Page 79: Rails routing from the outside in

Customizing Resourceful RoutesSpecifying 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

Page 80: Rails routing from the outside in

Customizing Resourceful RoutesSpecifying Constraints : Block form

# in config/routes.rb

constraints(id: /[A-Z][A-Z][0-9]+/) do resources :photos resources :accountsend

RUBY

블록 형식을 사용, 여러 라우트에 단일 제약을 적용할 수 있음·

80/98

Page 81: Rails routing from the outside in

Customizing Resourceful RoutesOverriding the Named Helpers

# in config/routes.rb

resources :photos, as: 'images'

RUBY

/photos로 시작하는 유입경로를 인식, PhotosController로 라우트:as 옵션의 값을 이용하여 헬퍼의 이름을 작명

·

·

81/98

Page 82: Rails routing from the outside in

Customizing Resourceful RoutesOverriding 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

Page 83: Rails routing from the outside in

Customizing Resourceful RoutesOverriding 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

Page 84: Rails routing from the outside in

Customizing Resourceful RoutesOverriding the new and edit Segments with scope

# in config/routes.rb

scope path_names: { new: 'make' } do resources :photos resources :articlesend

RUBY

scope 범위 내에 있는 모든 라우트의 new 액션명을 make로 대치·

84/98

Page 85: Rails routing from the outside in

Customizing Resourceful RoutesPrefixing 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

Page 86: Rails routing from the outside in

Customizing Resourceful RoutesPrefixing the Named Route Helper

# in config/routes.rb

scope 'admin', as: 'admin' do resources :photos, :accountsend

resources :photos, :accounts

RUBY

스코프 내 여러 리소스의 라우트 헬퍼 집합에 접두어를 붙이려면scope와 함께 :as 옵션을 사용

·

·

86/98

Page 87: Rails routing from the outside in

Customizing Resourceful RoutesPrefixing Routes with a Named Parameter

# in config/routes.rb

scope ':username' do resources :postsend# will route /bob/posts/1 to posts#show with params[:username] == 'bob'

RUBY

명명된 파라미터로의 라우트에 접두사를 붙이는 방법·

87/98

Page 88: Rails routing from the outside in

Customizing Resourceful RoutesRestricting the Routes Created

# in config/routes.rb

resources :photos, only: [:index, :show] resources :notes, except: :destroy

RUBY

레일스가 기본으로 생성하는 일곱 개의 레스트풀 라우트 기본 액션을 조정할 수 있음:only 옵션 - 지정된 액션만 생성, 나머지는 생성하지 않음:only와 :except를 사용하여 실제로 필요한 라우트만 생성하면 메모리 사용량을 줄이고 라우팅 프로세스의 속도를 높일 수있다.

·

·

·

88/98

Page 89: Rails routing from the outside in

Customizing Resourceful RoutesTralated Paths

# in config/routes.rb

scope(path_names: { new: 'neu', edit: 'bearbeiten' }) do resources :categories, path: 'Kategorien'end

RUBY

scope를 사용, 리소스에 의해 생성된 경로명을 변경할 수 있음·

89/98

Page 90: Rails routing from the outside in

Customizing Resourceful RoutesOverriding 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

Page 91: Rails routing from the outside in

Customizing Resourceful RoutesOverriding the Singular Form

# in config/initializers/inflections.rb

ActiveSupport::Inflector.inflections do |inflect| inflect.irregular 'tooth', 'teeth'end

RUBY

리소스의 단수 형식을 정의하기 위해 ActiveSupport::Inflector에 부가 규칙을 더함·

91/98

Page 92: Rails routing from the outside in

Customizing Resourceful RoutesUsing :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

Page 93: Rails routing from the outside in

Customizing Resourceful RoutesInspecting 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

Page 94: Rails routing from the outside in

Customizing Resourceful RoutesTesting Routes

라우트는 테스팅 전략에 포함되어야 한다고 권고테스트를 간단하게 할 수 있는 세 가지 내장 assertion을 제공

··

assert_generatesassert_recognizesassert_routing

···

94/98

Page 95: Rails routing from the outside in

Customizing Resourceful RoutesTesting 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

Page 96: Rails routing from the outside in

Customizing Resourceful RoutesTesting Routes: assert_recognizes

# 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

SH

assert_generates의 반대주어진 경로가 응용프로그램의 특정 지점을 인식하고 라우트함을 assert

·

·

96/98

Page 97: Rails routing from the outside in

Customizing Resourceful RoutesTesting 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

Page 98: Rails routing from the outside in

Thank you

Thanks to:

RoRLab MembersNaver D2Google (Slide Template)

···