πŸš€
Growth log
  • About me
  • I LEARNED
    • General
      • 개발자 κΏ€νŒ
      • κ·Έλ‘œμŠ€ν•΄ν‚Ή 기초
      • κ°œλ°œμžμ—κ²Œ 도메인 지식은 μ–Όλ§ˆλ‚˜ μ€‘μš”ν• κΉŒ?
      • DTO λ…ΌμŸμ— λŒ€ν•˜μ—¬
      • MSAλž€?
    • Seminar
      • ν…ŒμŠ€νŠΈ 컀버리지 100% - SLASH 21
      • TDDκ°€ μ‹€νŒ¨ν•˜λŠ” 이유 - by μ΄κ·œμ›λ‹˜
      • λŒ€κ·œλͺ¨ νŠΈλž˜ν”½ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ„±λŠ₯ νŠœλ‹ λ…Έν•˜μš° λ‹€ μ•Œλ € λ“œλ¦Ό|λΌμΈκ°œλ°œμ‹€λ‘
      • 결제 μ‹œμŠ€ν…œμ˜ SDK와 API λ””μžμΈ - SLASH 21
    • Web
      • SOP와 CORS
    • Spring & OOP
      • DTO vs VO
    • Ruby On Rails
      • Rails lib 디렉토리에 λŒ€ν•˜μ—¬
      • Rails의 concernsλž€?
      • Railsμ—μ„œμ˜ GC μž‘λ™μ›λ¦¬
      • Eager loading vs Lazy loading
      • Rails ν™˜κ²½ ꡬ성
      • ActionCable
      • πŸ“”Perfect ruby on rails
        • MVC νŒ¨ν„΄μΈ Rails
        • Ruby on Rails κΈ°λ³Έ - 컨트둀러
        • Ruby on Rails κΈ°λ³Έ - λ·°
        • Ruby on Rails κΈ°λ³Έ - λͺ¨λΈ
        • μŠ€μΊν΄λ”© κΈ°λŠ₯을 μ‚¬μš©ν•œ Rails 개발 기초
        • λ·° 개발
        • λͺ¨λΈ 개발
        • λͺ¨λΈ 개발 - 낙관적 λ™μ‹œ μ‹€ν–‰ μ œμ–΄
        • λͺ¨λΈ 개발 - μœ νš¨μ„± 검사 κ΅¬ν˜„
        • λͺ¨λΈ 개발 - Association
        • λͺ¨λΈ 개발 - 콜백
        • λͺ¨λΈ 개발 - λ§ˆμ΄κ·Έλ ˆμ΄μ…˜
        • λͺ¨λΈ 개발 - 데이터 μ΄ˆκΈ°ν™”
        • 컨트둀러 개발 - μš”μ²­ 정보 μΆ”μΆœ
        • 컨트둀러 개발 - 응닡
        • 컨트둀러 개발 - μƒνƒœ 관리
        • λΌμš°νŒ… - RESTful
        • λΌμš°νŒ… - RESTful μΈν„°νŽ˜μ΄μŠ€μ˜ μ‚¬μš©μž μ •μ˜ν™”
        • λΌμš°νŒ… - RESTful ν•˜μ§€ μ•Šμ€ 라우트 μ •μ˜
        • ν…ŒμŠ€νŠΈ
        • ν…ŒμŠ€νŠΈ - μ€€λΉ„
        • ν…ŒμŠ€νŠΈ - Unit ν…ŒμŠ€νŠΈ
        • ν…ŒμŠ€νŠΈ - Functional ν…ŒμŠ€νŠΈ
        • ν…ŒμŠ€νŠΈ - Integration ν…ŒμŠ€νŠΈ
        • ν΄λΌμ΄μ–ΈνŠΈ 개발 - Sprockets vs Webpacker
        • ν΄λΌμ΄μ–ΈνŠΈ 개발 - Sprockets
    • Node.js & Express
      • κΈ°λ³Έ κ°œλ…
      • npx
    • Programing Language
      • Java
        • JavaDoc에 λŒ€ν•΄
        • invocation에 λŒ€ν•΄μ„œ
        • μ–΄λ…Έν…Œμ΄μ…˜
        • μΆ”μƒν΄λž˜μŠ€ & μΈν„°νŽ˜μ΄μŠ€
        • Package
        • μ˜€λ²„λ‘œλ”© vs μ˜€λ²„λΌμ΄λ”©
      • Javascript
        • TCP School 훑어보기
          • νƒ€μž…
          • ν˜• λ³€ν™˜
          • λ³€μˆ˜
          • μ—°μ‚°μž
          • 반볡문
          • λ°°μ—΄(array)
          • ν•¨μˆ˜
          • ν•¨μˆ˜ - μŠ€μ½”ν”„μ™€ ν˜Έμ΄μŠ€νŒ…
          • ν•¨μˆ˜ - λ§€κ°œλ³€μˆ˜μ™€ 인수
          • ν•¨μˆ˜ - 미리 μ •μ˜λœ μ „μ—­ ν•¨μˆ˜
          • 객체
          • ν”„λ‘œν† νƒ€μž…
          • DOM
          • BOM - Window 객체
          • 이벀트(event)
      • Ruby
        • πŸ“”νΌνŽ™νŠΈ 루비
    • DB
      • Redis
        • Redis κ°œμš”
      • Index(인덱슀)?
      • DB Transaction & Lock
      • λ™μ‹œμ„± μ œμ–΄μ— κ΄€ν•˜μ—¬
      • Lock(잠금)μ΄λž€?
      • ActiveRecord lock vs with_lock
      • Table lock vs Row lock
      • WHERE 1=1 ꡬ문에 λŒ€ν•˜μ—¬
      • COUNT(*) vs COUNT(indexed column)
      • πŸ“•κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€ μ‹€μ „μž…λ¬Έ
      • πŸ“”SQL 첫걸음
      • πŸ“”λͺ¨λ‘μ˜ SQL
    • Design Patterns
      • Observer pattern
      • Flyweight pattern
      • Singleton pattern
    • OOP
      • πŸ“”μ˜€λΈŒμ νŠΈ
        • 6μž₯ λ©”μ‹œμ§€μ™€ μΈν„°νŽ˜μ΄μŠ€
      • ν΄λž˜μŠ€κ°„ 관계 간단 정리
    • Regex
    • Collaboration
      • Git
      • Sourcetree
  • DAILY REVIEW
    • 2021
      • August
        • 2021-08-25(Wed)
        • 2021-08-23(Mon)
        • 2021-08-11(Wed)
        • 2021-08-04(Wed)
        • 2021-08-03(Tue)
        • 2021-08-02(Mon)
      • July
        • 2021-07-29(Thu)
        • 2021-07-26(Mon)
        • 2021-07-23(Fri)
        • 2021-07-22(Thu)
        • 2021-07-21(Wed)
        • 2021-07-20(Tue)
        • 2021-07-19(Mon)
        • 2021-07-15(Thu)
        • 2021-07-14(Wed)
        • 2021-07-13(Tue)
        • 2021-07-12(Mon)
      • June
        • 2021-06-05(Sat)
        • 2021-06-04(Fri)
        • 2021-06-03(Thu)
        • 2021-06-02(Wed)
        • 2021-06-01(Tue)
      • May
        • 2021-05-31(Mon)
        • 2021-05-29(Sat)
        • 2021-05-28(Fri)
        • 2021-05-27(Thu)
        • 2021-05-26(Wed)
        • 2021-05-25(Tue)
        • 2021-05-24(Mon)
        • 2021-05-22(Sat)
        • 2021-05-21(Fri)
        • 2021-05-20(Thu)
        • 2021-05-19(Wed)
        • 2021-05-18(Tue)
        • 2021-05-17(Mon)
        • 2021-05-15(Sat)
        • 2021-05-13(Thu)
        • 2021-05-12(Wed)
        • 2021-05-11(Tue)
        • 2021-05-10(Mon)
        • 2021-05-03(Mon)
      • April
        • 2021-04-30(Fri)
        • 2021-04-29(Thu)
        • 2021-04-28(Wed)
        • 2021-04-27(Tue)
        • 2021-04-26(Mon)
        • 2021-04-24(Sat)
        • 2021-04-23(Fri)
        • 2021-04-21(Wed)
        • 2021-04-20(Tue)
        • 2021-04-19(Mon)
        • 2021-04-18(Sun)
        • 2021-04-16(Fri)
        • 2021-04-15(Thu)
        • 2021-04-14(Wed)
        • 2021-04-12(Mon)
        • 2021-04-11(Sun)
        • 2021-04-09(Fri)
        • 2021-04-08(Thu)
        • 2021-04-06(Tue)
        • 2021-04-05(Mon)
        • 2021-04-04(Sun)
        • 2021-04-03(Sat)
        • 2021-04-02(Fri)
        • 2021-04-01(Thu)
      • March
        • 2021-03-29(Mon)
        • 2021-03-28(Sun)
        • 2021-03-26(Fri)
        • 2021-03-25(Thu)
        • 2021-03-24(Wed)
        • 2021-03-23(Tue)
        • 2021-03-22(Mon)
        • 2021-03-21(Sun)
        • 2021-03-20(Sat)
        • 2021-03-17(Wed)
        • 2021-03-16(Tue)
        • 2021-03-15(Mon)
        • 2021-03-12(Fri)
        • 2021-03-11(Thu)
        • 2021-03-10(Wed)
        • 2021-03-09(Tue)
        • 2021-03-08(Mon)
        • 2021-03-07(Sun)
        • 2021-03-05(Fri)
        • 2021-03-03(Wed)
        • 2021-03-02(Tue)
        • 2021-03-01(Mon)
      • Feb
        • 2021-02-26(Fri)
        • 2021-02-25(Thu)
        • 2021-02-24(Wed)
        • 2021-02-23(Tue)
        • 2021-02-22(Mon)
        • 2021-02-19(Fri)
        • 2021-02-18(Thu)
        • 2021-02-17(Wed)
        • 2021-02-16(Tue)
        • 2021-02-15(Mon)
        • 2021-02-14(Sun)
        • 2021-02-13(Sat)
        • 2021-02-12(Fri)
        • 2021-02-10(Wed)
        • 2021-02-09(Tue)
        • 2021-02-08(Mon)
        • 2021-02-07(Sun)
        • 2021-02-05(Fri)
        • 2021-02-03(Wed)
        • 2021-02-02(Tue)
        • 2021-02-01(Mon)
      • Jan
        • 2021-01-29(Fri)
        • 2021-01-28(Thu)
        • 2021-01-27(Wed)
        • 2021-01-26(Tue)
        • 2021-01-25(Mon)
        • 2021-01-23(Sat)
        • 2021-01-22(Fri)
        • 2021-01-20(Wed)
        • 2021-01-19(Tue)
        • 2021-01-18(Mon)
        • 2021-01-12(Tue)
        • 2020-01-11(Mon)
        • 2021-01-08(Fri)
        • 2021-01-07(Thu)
        • 2021-01-06(Wed)
        • 2021-01-05(Tue)
        • 2021-01-04(Mon)
        • 2021-01-01(Fri)
    • 2020
      • Dec
        • 2020-12-30(Thu)
        • 2020-12-25(Fri)
        • 2020-12-24(Thu)
        • 2020-12-23(Wed)
        • 2020-12-22(Tue)
        • 2020-12-21(Mon)
        • 2020-12-18 (Fri)
      • Nov
        • 2020-11-30(Mon)
        • 2020-11-28(Sat)
        • 2020-11-26(Thu)
        • 2020-11-25(Wed)
        • 2020-11-24(Tue)
        • 2020-11-23(Mon)
        • 2020-11-22(Sun)
        • 2020-11-20(Fri)
        • 2020-11-19(Thu)
        • 2020-11-18(Wed)
        • 2020-11-17(Tue)
        • 2020-11-14(Sat)
        • 2020-11-13(Fri)
        • 2020-11-12(Thu)
        • 2020-11-11(Wed)
        • 2020-11-09(Mon)
        • 2020-11-07(Sat)
        • 2020-11-05(Thu)
        • 2020-11-04(Wed)
        • 2020-11-03(Tue)
        • 2020-11-02(Mon)
    • Good article 아카이빙
Powered by GitBook
On this page
  • 상세 ν•™μŠ΅ λ‚΄μš©
  • λΌμš°νŒ…
  • RESTful μΈν„°νŽ˜μ΄μŠ€
  • resources λ©”μ„œλ“œ
  • resource λ©”μ„œλ“œ
  • RESTful μΈν„°νŽ˜μ΄μŠ€μ˜ μ‚¬μš©μž μ •μ˜ν™”
  • RESTful ν•˜μ§€ μ•Šμ€ 라우트 μ •μ˜
  • ν…ŒμŠ€νŠΈ
  • ν…ŒμŠ€νŠΈ μ€€λΉ„
  • ν•™μŠ΅ λ‚΄μš©μ— λŒ€ν•œ 개인적인 총평

Was this helpful?

  1. DAILY REVIEW
  2. 2021
  3. Jan

2021-01-04(Mon)

ν•­λͺ©

λ‚΄μš©

ν•™μŠ΅ λ‚ μ§œ

2021-01-04(μ›”)

ν•™μŠ΅ μ‹œκ°„

12:00~24:00

ν•™μŠ΅ λ²”μœ„ 및 주제

λ£¨λΉ„μ˜¨λ ˆμΌμ¦ˆ λΌμš°νŒ…, ν…ŒμŠ€νŠΈ

ν•™μŠ΅ λͺ©ν‘œ

νΌνŽ™νŠΈ λ£¨λΉ„μ˜¨λ ˆμΌμ¦ˆ λΌμš°νŒ…, ν…ŒμŠ€νŠΈ 챕터λ₯Ό λ…νŒŒν•œλ‹€.

λ™λ£Œ ν•™μŠ΅ 방법

-

상세 ν•™μŠ΅ λ‚΄μš©

책을 ν›‘μœΌλ©° μ•„λž˜μ²˜λŸΌ κ°„λ‹¨ν•˜κ²Œ λ©”λͺ¨λ₯Ό μ§„ν–‰ν–ˆλ‹€.

λΌμš°νŒ…

RESTful μΈν„°νŽ˜μ΄μŠ€

RESTful μΈν„°νŽ˜μ΄μŠ€λŠ” REST의 νŠΉμ§•μ„ κ°€μ§„ 라우트λ₯Ό λ§ν•œλ‹€. RESTλŠ” HTTP λ©”μ„œλ“œμ™€ CRUDλ₯Ό λŒ€μ‘μ‹œν‚€λŠ” 것이라 μƒκ°ν•˜λ©΄ λœλ‹€.

  • μΆ”μΆœ: GET

  • 생성: POST

  • λ³€κ²½: PATCH

  • 제거: DELETE

RailsλŠ” μ›μΉ™μ μœΌλ‘œ RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό 기반으둜 라우트λ₯Ό μ„€κ³„ν•œλ‹€. λΉ„RESTful적인 라우트λ₯Ό μ„€μ •ν•  μˆ˜λ„ μžˆμ§€λ§Œ, Railsμ—μ„œ μ œκ³΅ν•˜λŠ” form_for, url_for, link_to λ“±μ˜ λ·° ν—¬νΌλŠ” RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ „μ œλ‘œ μ„€κ³„λ˜μ–΄ μžˆμœΌλ―€λ‘œ μ™ λ§Œν•˜λ©΄ RESTful적인 라우트λ₯Ό μ‚¬μš©ν•˜μž.

resources λ©”μ„œλ“œ

예λ₯Ό λ“€μ–΄ μ•„λž˜ μ½”λ“œλ₯Ό 적으면 μ•„λž˜ ν‘œμ²˜λŸΌ URL둜 μ•‘μ…˜μ΄ λ§€ν•‘λœλ‹€.

Railbook::Application.routes.draw do
  resources :users
  ...
end

URL

μ•‘μ…˜

HTTP λ©”μ„œλ“œ

μ—­ν• 

/users(.:format)

index

GET

μ‚¬μš©μž λͺ©λ‘ 생성

/users/:id(.:format)

show

GET

각각의 μ‚¬μš©μž 상세 ν™”λ©΄ 생성

/users/new(.:format)

new

GET

μ‹ κ·œ μ‚¬μš©μž μΆ”κ°€ ν™”λ©΄ 생성

/users(.:format)

create

POST

μ‹ κ·œ μ‚¬μš©μž ν™”λ©΄μœΌλ‘œλΆ€ν„°μ˜ μž…λ ₯을 λ°›μ•„ 등둝 처리

/users/:id/edit(.:format)

edit

GET

기쑴의 μ‚¬μš©μž νŽΈμ§‘ ν™”λ©΄ 생성

/users/:id(.:format)

update

PATCH/PUT

νŽΈμ§‘ ν™”λ©΄μœΌλ‘œλΆ€ν„° μž…λ ₯을 λ°›μ•„ μˆ˜μ • 처리

/users/:id(.:format)

destory

DELETE

λͺ©λ‘ ν™”λ©΄μ—μ„œ μ„ νƒν•œ 데이터 제거 처리

λ˜ν•œ resources λ©”μ„œλ“œλŠ” λ·° 헬퍼(link_to λ“±)μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” Url 헬퍼도 μžλ™μœΌλ‘œ μƒμ„±ν•œλ‹€.

헬퍼 이름(_path)

헬퍼 이름(_url)

리턴 κ°’(경둜)

users_path

users_url

/users

user_path(id)

user_url(id)

/users/:id

new_user_path

new_user_url

/users/new

edit_user_path(id)

edit_user_url(id)

/users/:id/edit

μ΄λŸ¬ν•œ 헬퍼λ₯Ό μ‚¬μš©ν•˜λ©΄ 링크λ₯Ό 보닀 μ§κ΄€μ μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλŠ” 것은 λ¬Όλ‘ , 라우트 μ •μ˜μ— μ˜μ‘΄ν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€.

resource λ©”μ„œλ“œ

예λ₯Ό λ“€μ–΄ μ•„λž˜ μ½”λ“œλ₯Ό 적으면 μ•„λž˜ ν‘œμ²˜λŸΌ URL둜 μ•‘μ…˜μ΄ λ§€ν•‘λœλ‹€.

Railbook::Application.routes.draw do
  resource :config
  ...
end

URL

μ•‘μ…˜

HTTP λ©”μ„œλ“œ

μ—­ν• 

/config(.:format)

show

GET

μ„€μ • 정보 ν™”λ©΄ ν‘œμ‹œ 상세 ν™”λ©΄ 생성

/config/new(.:format)

new

GET

μ‹ κ·œ μ„€μ • μΆ”κ°€ ν™”λ©΄ 생성

/config(.:format)

create

POST

등둝 ν™”λ©΄μ—μ„œ μž…λ ₯을 λ°›μ•„ 등둝 처리

/config/edit(.:format)

edit

GET

κΈ°μ‘΄ μ„€μ • μˆ˜μ • ν™”λ©΄ ν‘œμ‹œ

/config(.:format)

update

PATCH/PUT

μˆ˜μ • ν™”λ©΄μ—μ„œ μž…λ ₯을 λ°›μ•„ μˆ˜μ • 처리

/config(.:format)

destroy

DELETE

μ§€μ •λœ μ„€μ • 정보λ₯Ό 제거 처리

resources λ©”μ„œλ“œμ™€ λΉ„μŠ·ν•˜μ§€λ§Œ, index μ•‘μ…˜μ΄ μ •μ˜λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ show, edit, delete λ“±μ—μ„œ :idλ₯Ό 맀개 λ³€μˆ˜λ‘œ λ°›μ§€ μ•ŠλŠ”λ‹€λŠ” 점이 λ‹€λ₯΄λ‹€.

  • μ°Έκ³ 1) resource λ©”μ„œλ“œλ„ config λ¦¬μ†ŒμŠ€κ°€ ConfigsController둜 λ§€ν•‘λœλ‹€.

  • μ°Έκ³ 2) http://localhost:3000/rails/info/routes둜 μ ‘κ·Όν•˜λ©΄ λΈŒλΌμš°μ €λ‘œλ„ 라우트 μ •μ˜λ₯Ό 확인할 수 μžˆλ‹€.

RESTful μΈν„°νŽ˜μ΄μŠ€μ˜ μ‚¬μš©μž μ •μ˜ν™”

resources, resource λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ RESTfulν•œ μ •ν˜•μ μΈ 라우트λ₯Ό μžλ™μœΌλ‘œ 생성할 수 μžˆλ‹€. ν•˜μ§€λ§Œ μ‹€μ œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“ λ‹€λ©΄ ν‘œμ€€μ μΈ κ·œμΉ™λ§ŒμœΌλ‘œλŠ” λͺ¨λ“  것을 κ΅¬ν˜„ν•  수 μ—†μœΌλ―€λ‘œ μ€‘μš”ν•œ μ˜΅μ…˜λ“€μ΄ 뭐가 μžˆλŠ”μ§€λŠ” ν™•μΈν•΄λ‘˜ ν•„μš”κ°€ μžˆλ‹€.

라우트 맀개 λ³€μˆ˜ μ œμ•½ 쑰건 - contraints μ˜΅μ…˜

사싀 라우트 맀개 λ³€μˆ˜μ™€ κ΄€λ ¨λœ μœ νš¨μ„± κ²€μ‚¬λŠ” λͺ¨λΈμ—μ„œ ν•˜λŠ” 것이 κΈ°λ³Έμ΄μ§€λ§Œ, λΌμš°νŠΈμ—μ„œ μ²˜λ¦¬ν•˜λ©΄ μ›μΉ˜ μ•ŠλŠ” 값을 보닀 ν™•μ‹€ν•˜κ²Œ 차단할 수 μžˆλ‹€.

constraints: { <맀개 λ³€μˆ˜ 이름>: <μ •κ·œ ν‘œν˜„μ‹> } ν˜•νƒœλ‘œ 라우트 맀개 λ³€μˆ˜μ˜ μ œμ•½ 쑰건을 μ§€μ •ν•  수 μžˆλ‹€. μ•„λž˜μ²˜λŸΌ!

Railbook::Application.routes.draw do
  resources :books, constraints: { id: /[0-9]{1,2}/ }
  ...
end

μ—¬λŸ¬ 개의 λ¦¬μ†ŒμŠ€μ— λ™μΌν•œ μ œμ•½ 쑰건을 λΆ€μ—¬ν•  λ•ŒλŠ” λ‹€μŒκ³Ό 같이 블둝 ν˜•μ‹μœΌλ‘œ μ œμ•½ μ‘°κ²…λŠ˜ μž‘μ„±ν•  수 μžˆλ‹€.

constraints(id: /[0-9]{1,2}/) do
  resources :books
  resources :reviews
end

λ³΅μž‘ν•œ μ œμ•½ 쑰건 μ„€μ • - μ œμ•½ 클래슀 μ •μ˜

μ •κ·œ ν‘œν˜„μ‹λ§ŒμœΌλ‘œλŠ” ν‘œν˜„ν•  수 μ—†λŠ” λ³΅μž‘ν•œ μ œμ•½ 쑰건을 μ„€μ •ν•˜κ³  μ‹Άλ‹€λ©΄ μ œμ•½ 클래슀λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€. μ œμ•½ ν΄λž˜μŠ€μ— 쑰건을 λ§Œλ“€ λ•ŒλŠ” matches? λ©”μ„œλ“œλ₯Ό λ§Œλ“€μ–΄μ£ΌκΈ°λ§Œ ν•˜λ©΄ λœλ‹€.

matches? λ©”μ„œλ“œλŠ” λ‹€μŒκ³Ό 같이 κ·œμΉ™μ„ μ§€μΌœμ•Όν•œλ‹€.

  • 맀개 λ³€μˆ˜λ‘œ μš”μ²­ 정보(request 객체)λ₯Ό λ°›μŒ.

  • 리턴 κ°’μœΌλ‘œλŠ” 라우트λ₯Ό μœ νš¨ν™”ν• μ§€μ— λŒ€ν•œ true λ˜λŠ” falseλ₯Ό 리턴

μ˜ˆμ‹œλ₯Ό 보자. μ•„λž˜μ²˜λŸΌ μ œμ•½ 클래슀λ₯Ό μ •μ˜ν–ˆλ‹€λ©΄,

class TimeConstaint
  def matches?(request)
    current = Time.now
    current.hour >= 9 && current.hour < 18
  end
end

μ•„λž˜μ²˜λŸΌ μ œμ•½ 클래슀λ₯Ό λΆˆλŸ¬μ™€μ„œ constraint μ˜΅μ…˜μœΌλ‘œ μ „λ‹¬λ§Œ ν•΄μ£Όλ©΄ λœλ‹€.

require 'TimeConstraint'
​
Railbook::Application.routes.draw.do
  resources :books, constraints: TimeConstraint.new
  ...
end

form 맀개 λ³€μˆ˜ 제거 - form μ˜΅μ…˜

resources와 resource λ©”μ„œλ“œλ‘œ μ •μ˜λœ λͺ¨λ“  λΌμš°νŠΈλŠ” ~(.:format)이 λΆ™μ–΄μžˆλ‹€. λ”°λΌμ„œ ~books.xml λ˜λŠ” ~/books.json처럼 좜λ ₯ ν˜•μ‹μ„ ν™•μž₯자 ν˜•νƒœλ‘œ μ§€μ •ν•  μˆ˜λ„ μžˆλ‹€.

ν•˜μ§€λ§Œ λ¦¬μ†ŒμŠ€μ— λ”°λΌμ„œλŠ” μ—¬λŸ¬ ν˜•μ‹μ— λŒ€μ‘ν•˜μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€. 이런 κ²½μš°μ—” format μ˜΅μ…˜μ„ false둜 μ§€μ •ν•˜μž. 그럼 URL νŒ¨ν„΄μ—μ„œ ~(.:format)이 제거된 λΌμš°νŠΈκ°€ μƒμ„±λœλ‹€.

컨트둀러 ν΄λž˜μŠ€μ™€ Url ν—¬νΌμ˜ 이름 μˆ˜μ • - controller와 as μ˜΅μ…˜

resources와 resource λ©”μ„œλ“œλŠ” 기본적으둜 μ§€μ •λœ λ¦¬μ†ŒμŠ€ 이름을 기반으둜 λŒ€μ‘λ˜λŠ” 컨트둀러λ₯Ό κ²°μ •ν•˜κ³  Url 헬퍼λ₯Ό μƒμ„±ν•œλ‹€.

λͺ¨λ“ˆ λ‚΄λΆ€μ˜ 컨트둀러λ₯Ό λ§΅ν•‘ - namespace와 scope 블둝

컨트둀러 클래슀의 μˆ˜κ°€ λ§Žμ•„μ§€λ©΄ λͺ¨λ“ˆμ„ μ‚¬μš©ν•΄ 컨트둀러λ₯Ό ν΄λ”λ‘œ μ •λ¦¬ν•˜κ³  싢은 κ²½μš°κ°€ μžˆμ„ 것이닀. μ•„λž˜μ²˜λŸΌ 컨트둀러 클래슀λ₯Ό μƒμ„±ν•˜λ©΄ λœλ‹€.

rails generate controller Admin::Books

μ΄λ ‡κ²Œ ν•˜λ©΄ Admin::BooksControllerκ°€ controllers/admin 폴더 μ•„λž˜μ— books_controller.rbλΌλŠ” μ΄λ¦„μœΌλ‘œ μƒμ„±λœλ‹€.

μ΄λ ‡κ²Œ λͺ¨λ“ˆλ‘œ 컨트둀러 클래슀λ₯Ό 생성할 κ²½μš°μ—λŠ” ν…œν”Œλ¦Ώμ„ /views/<λͺ¨λ“ˆ 이름>/<컨트둀러 이름>폴더에 λ„£μœΌλ©΄ λœλ‹€.

이처럼 λͺ¨λ“ˆμ„ μ‚¬μš©ν•œ 컨트둀러 ν΄λž˜μŠ€μ— RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•˜λ €λ©΄ μ•„λž˜μ²˜λŸΌ namespace 블둝을 μ‚¬μš©ν•˜λ©΄ λœλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ /admin/books λ˜λŠ” /admin/books/:id와 같은 URL νŒ¨ν„΄κ³Ό, admin_books_path λ˜λŠ” admin_book_path(id)와 같은 URL 헬퍼가 μƒμ„±λœλ‹€.

namespace :admin do
  resources :books
end

λ§Œμ•½μ— λͺ¨λ“ˆμ„ μΈμ‹λ§Œ ν•˜κ³  URL νŒ¨ν„΄κ³Ό URL ν—¬νΌμ—λŠ” 영ν–₯을 μ£Όκ³  μ‹Άμ§€ μ•Šμ€ κ²½μš°μ—λŠ” μ•„λž˜μ²˜λŸΌ scope 블둝을 μ‚¬μš©ν•˜λ©΄ λœλ‹€.

scope module: :admin do
  resources :books
end

RESTful μΈν„°νŽ˜μ΄μŠ€μ— μ•‘μ…˜ μΆ”κ°€ - collectionκ³Ό member 블둝

collectionκ³Ό member 블둝을 μ‚¬μš©ν•˜λ©΄ resources와 resource λ©”μ„œλ“œλ‘œ μžλ™ μƒμ„œλ˜λŠ” 라우트 외에 μ›ν•˜λŠ” μ•‘μ…˜μ„ μΆ”κ°€ν•  수 μžˆλ‹€.

resources :name do
  [collection do
    method action
    ...
  end]
  [member do
    method action
    ...
  end]
end

collection 블둝은 μ—¬λŸ¬ 객체λ₯Ό λ‹€λ£¨λŠ” μ•‘μ…˜μ„, member 블둝은 ν•˜λ‚˜μ˜ 객체λ₯Ό λ‹€λ£¨λŠ” μ•‘μ…˜μ„ λ§Œλ“€ λ•Œ μ‚¬μš©ν•œλ‹€.

RESTful μΈν„°νŽ˜μ΄μŠ€μ˜ μ•‘μ…˜μ„ λ¬΄νš¨ν™” - only와 except μ˜΅μ…˜

collection, member 블둝과 λ°˜λŒ€λ‘œ 기본적으둜 μƒμ„±λ˜λŠ” μ•‘μ…˜μ˜ 일뢀λ₯Ό λ¬΄νš¨ν™”ν•˜κ³  싢을 λ•ŒλŠ” only λ˜λŠ” except μ˜΅μ…˜μ„ μ§€μ •ν•œλ‹€.

라우트 μ •μ˜λ₯Ό μΆ”κ°€ λ˜λŠ” λ¬΄νš¨ν™”ν•˜λŠ” 것이 μ•„λ‹ˆλΌ ν‘œμ€€ μ•‘μ…˜μΈ new μ•‘μ…˜, edit μ•‘μ…˜κ³Ό κ΄€λ ¨λœ URL을 λ³€κ²½ν•˜κ³  싢은 κ²½μš°μ—λŠ” :path_names μ˜΅μ…˜μ„ μ§€μ •ν•œλ‹€.

계측 ꡬ쑰λ₯Ό κ°€μ§„ λ¦¬μ†ŒμŠ€ ν‘œν˜„ - resources λ©”μ„œλ“œ 쀑첩

λ¦¬μ†ŒμŠ€λ“€μ΄ μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λ‚΄λΆ€μ—μ„œ 계측 관계λ₯Ό κ°–λŠ” κ²½μš°κ°€ μžˆλ‹€. 예λ₯Ό λ“€μ–΄, books λ¦¬μ†ŒμŠ€(λ„μ„œ 정보)λŠ” reviews λ¦¬μ†ŒμŠ€(λ„μ„œ 리뷰)λ₯Ό ν¬ν•¨ν•œλ‹€. μ΄λŸ¬ν•œ λ¦¬μ†ŒμŠ€ 계측 κ΄€κ³„λŠ” has_many λ˜λŠ” belongs_to λ“±μ˜ λͺ¨λΈ Association으둜 λ‚˜νƒ€λ‚Έλ‹€.

μ΄λŸ¬ν•œ λ¦¬μ†ŒμŠ€(λͺ¨λΈ)의 κ΄€κ³„λŠ” URLλ‘œλ„ ν‘œν˜„ν•΄μ£ΌλŠ” 것이 직관적이닀. κ°€λ Ή λ„μ„œ1의 리뷰 μ •λ³΄λŠ” ~/books/1/reviews처럼 λ‚˜νƒ€λ‚΄λŠ” 것이 μ’‹λ‹€.

μ΄λŸ¬ν•œ κ΄€κ³„λŠ” resources와 resource λ©”μ„œλ“œλ₯Ό μ€‘μ²©ν•΄μ„œ λ‚˜νƒ€λ‚Έλ‹€.

resources :books do
  resources :reviews
end

이러면 URL 헬퍼에 book_μ΄λΌλŠ” 접두사가 λΆ™λŠ”λ‹€. resources와 resource λ©”μ„œλ“œλŠ” κ³„μ†ν•΄μ„œ 쀑첩할 수 μžˆμ§€λ§Œ, 계측은 2단계 κΉŒμ§€λ§Œ λ§Œλ“œλŠ” 것이 λ¬΄λ‚œν•˜λ‹€.

λ¦¬μ†ŒμŠ€μ˜ 얕은 쀑첩 ν‘œν˜„ - shallow μ˜΅μ…˜

μ•„λž˜μ²˜λŸΌ shallow μ˜΅μ…˜μ„ μ“°λ©΄ '얕은 URL'이 μƒμ„±λœλ‹€.

resources :books do
  resources :reviews, shallow: true
end

라우트 μ •μ˜ 재이용 - concern λ©”μ„œλ“œμ™€ concerns μ˜΅μ…˜

concern λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ κ³΅ν†΅λ˜λŠ” λ‚΄μš©μ„ μ—¬λŸ¬ 개의 라우트 μ •μ˜μ— 넣을 수 μžˆλ‹€.

RESTful ν•˜μ§€ μ•Šμ€ 라우트 μ •μ˜

λͺ¨λ“  것을 RESTfulν•˜κ²Œ λ§Œλ“€ 수 μžˆλŠ” 것은 μ•„λ‹ˆλ‹€. 이럴 땐 λ¬΄λ¦¬ν•΄μ„œ RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ μš©ν•˜λ € λ“€μ§€ 말고, κ°„λ‹¨ν•˜κ²Œ RESTful ν•˜μ§€ μ•Šμ€ 라우트λ₯Ό μ •μ˜ν•΄λ³΄μž.

match λ©”μ„œλ“œ

via μ˜΅μ…˜μ—λŠ” νŠΉλ³„ν•œ κ°’μœΌλ‘œ :all(λͺ¨λ“  HTTP λ©”μ„œλ“œ ν—ˆμš©)을 μ§€μ •ν•  μˆ˜λ„ μžˆλ‹€. ν•˜μ§€λ§Œ CSRF 곡격의 간접적인 원인이 λ˜λ―€λ‘œ 가급적 μ‚¬μš©ν•˜μ§€ 말자.

λ‹€μ–‘ν•œ RESTful ν•˜μ§€ μ•Šμ€ 라우트 ν‘œν˜„

μ˜ˆμ‹œλ₯Ό 보자.

get '/blogs/:user_id' => 'blogs#index'
get 'hello/view'
get 'articles(/:category)' => 'articles#index', defaults: { category: 'general', format: 'xml'}
get 'blogs/:user_id' => 'blogs#index', constraints: { user_id: /[A-Za-z]{3, 7}/ }
get ':controller(/:action(/:id))', controller: /common|/[^\/]+/
get 'articles' => 'main#index', as: :top
get 'articles/*category/:id' => 'articles#category'
get '/books/:id' => redirect('/articles/%{id}')
get '/books/:id' => redirect {|p, req| "/articles/#{p[:id].to_i + 10000}"}

루트 λ§€ν•‘ μ •μ˜ - root λ©”μ„œλ“œ

λ£¨νŠΈμ— λŒ€μ‘ν•˜λŠ” 라우트λ₯Ό μ„€μ •ν•  λ•ŒλŠ” root λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œλ‹€. root λ©”μ„œλ“œλŠ” 일반적으둜 routes.rb의 λ§ˆμ§€λ§‰μ— μž‘μ„±ν•œλ‹€.

ν…ŒμŠ€νŠΈ

μžλ™ν™”λœ ν…ŒμŠ€νŠΈμ€ μ•ˆμ •μ μ΄κ³  μœ μ—°ν•œ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ λ§Œλ“œλŠ”λ° ν•„μˆ˜μš”μ†Œλ‹€. RailsλŠ” 초기 버전뢀터 이런 μžλ™ν™”λœ ν…ŒμŠ€νŠΈλ₯Ό ꡉμž₯히 μ€‘μš”μ‹œν•˜κ³  있고, μ•„λž˜ ν…ŒμŠ€νŠΈλ“€μ„ μ§€μ›ν•œλ‹€.

  • Unit ν…ŒμŠ€νŠΈ: λͺ¨λΈ λ˜λŠ” λ·° ν—¬νΌμ˜ λ™μž‘ 확인

  • Functional ν…ŒμŠ€νŠΈ: μ»¨νŠΈλ‘€λŸ¬μ™€ ν…œν”Œλ¦Ώμ˜ 호좜 κ²°κ³Ό 확인(μƒνƒœ μ½”λ“œ λ˜λŠ” ν…œν”Œλ¦Ώ λ³€μˆ˜ 뷰의 좜λ ₯ κ²°κ³Ό λ“±)

  • Integration ν…ŒμŠ€νŠΈ: μ—¬λŸ¬ 개의 컨트둀러λ₯Ό λ„˜λ‚˜λ“€λ©° μ‚¬μš©μžμ˜ μ‹€μ œ μ‘°μž‘μ„ λͺ¨λ°©ν•˜κ³  κ²°κ³Ό 확인

μ±…μ—μ„œλŠ” Test::Unit에 λŒ€ν•΄ μ„€λͺ…ν•œλ‹€.

ν…ŒμŠ€νŠΈ μ€€λΉ„

μš°μ„  ν…ŒμŠ€νŠΈλ₯Ό ν•˜λ €λ©΄ λ°μ΄ν„°λ² μ΄μŠ€μ™€ ν…ŒμŠ€νŠΈ μ „μš© 데이터가 ν•„μš”ν•˜λ‹€. μ˜ˆμ‹œλ₯Ό λ”°λΌκ°€λ³΄μž.

1. ν…ŒμŠ€νŠΈ 데이터 베이슀 ꡬ좕

μ•„λž˜μ²˜λŸΌ rake λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•΄μ„œ ν…ŒμŠ€νŠΈ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό κ΅¬μΆ•ν•œλ‹€.

rake db:migrate
rake db:test:load

rake db:migrate λͺ…λ Ήμ–΄λ‘œ λ―Έμ‹€ν–‰ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜μ„ μ‹€ν–‰ν•˜κ³ , schema.rbλ₯Ό μ΅œμ‹  μƒνƒœλ‘œ μ—…λ°μ΄νŠΈν•œ 뒀에 rake db:test:load λͺ…λ Ήμ–΄λ‘œ schema.rbλ₯Ό 기반으둜 ν•˜λŠ” ν…ŒμŠ€νŠΈ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€. μ΄λ ‡κ²Œλ§Œ ν•˜λ©΄ 개발 λ°μ΄ν„°λ² μ΄μŠ€μ™€ 같은 ꡬ쑰둜 ν…ŒμŠ€νŠΈ λ°μ΄ν„°λ² μ΄μŠ€κ°€ κ΅¬μΆ•λœλ‹€.

ν…ŒμŠ€νŠΈ λ°μ΄ν„°λ² μ΄μŠ€κ°€ 잘 κ΅¬μΆ•λ˜μ—ˆλŠ”μ§€ ν…ŒμŠ€νŠΈ ν™˜κ²½ λ°μ΄ν„°λ² μ΄μŠ€λ‘œ μ ‘μ†ν•˜μ—¬ 확인할 수 μžˆλ‹€. rails λ²„μ „λ³„λ‘œ λͺ…λ Ήμ–΄κ°€ λ‹€λ₯΄λ‹ˆ μ£Όμ˜ν•  것.

  • Rails 3, 4: rails dbconsole test

  • Rails 5, 6: rails dbconsole -e test

    2. ν…ŒμŠ€νŠΈ 데이터 μ€€λΉ„

    ν”½μŠ€μ²˜λ₯Ό test/fixtures 디렉토리에 λ„£μ–΄μ£Όμž.

    Unit ν…ŒμŠ€νŠΈ

    Unit ν…ŒμŠ€νŠΈ(λ‹¨μœ„ ν…ŒμŠ€νŠΈ)λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ κ΅¬μ„±ν•˜κ³  μžˆλŠ” 라이브러리(μ£Όμš” λͺ¨λΈ λ“±)κ°€ μ œλŒ€λ‘œ μž‘λ™ν•˜λŠ”μ§€ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈμ΄λ‹€.

    models ν…ŒμŠ€νŠΈ

    이후 rake test:models λͺ…λ Ήμ–΄λ‘œ λͺ¨λΈ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•œλ‹€. λ§Œμ•½ νŠΉμ •ν•œ ν…ŒμŠ€νŠΈ 슀크립트λ₯Ό μ§€μ •ν•˜κ³  μ‹€ν–‰ν•˜λ €λ©΄ rake test:models ν…ŒμŠ€νŠΈ_슀크립트_경둜 λ₯Ό μ‹€ν–‰μ‹œν‚€λ©΄ λœλ‹€.

    ν…ŒμŠ€νŠΈ λ©”μ„œλ“œκ°€ μ—¬λŸ¬ 개 μžˆμ„ λ•ŒλŠ” μ‹€ν–‰ μˆœμ„œκ°€ λ§ˆμŒλŒ€λ‘œμ΄λ―€λ‘œ μ‹€ν–‰ μˆœμ„œμ— μ˜μ‘΄ν•˜λŠ” ν…ŒμŠ€νŠΈ λ©”μ„œλ“œλŠ” μž‘μ„±ν•˜μ§€ μ•Šλ„λ‘ ν•˜μž.

    RailsλŠ” ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•  λ•Œ ν”½μŠ€μ²˜λ₯Ό λ°μ΄ν„°λ² μ΄μŠ€μ— λ‘œλ“œν•˜λŠ” κ²ƒλΏλ§Œ μ•„λ‹ˆλΌ, ν…ŒμŠ€νŠΈ μŠ€ν¬λ¦½νŠΈμ—μ„œ μ΄μš©ν•  수 있게 ν•΄μ‹œλ‘œ μ „κ°œν•œλ‹€.

    예λ₯Ό λ“€μ–΄ books.yml 내뢀에 :islbλΌλŠ” ν‚€λ‘œ μ •μ˜λœ λ ˆμ½”λ“œκ°€ μžˆλ‹€λ©΄, books(:jslib)에 μ ‘κ·Όν•  수 μžˆλ‹€.

    view helper ν…ŒμŠ€νŠΈ

    /test/helpers 폴더 내뢀에 <컨트둀러>_helper_test.rb처럼 ν…ŒμŠ€νŠΈ 슀크립트λ₯Ό λ§Œλ“€κ³  μ—­μ‹œ testλ©”μ„œλ“œλ‘œ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•œ λ‹€μŒ rake test:helpers λͺ…λ Ήμ–΄λ‘œ μ‹€ν–‰ν•˜μž.

    μ—­μ‹œλ‚˜ λ§Œμ•½ νŠΉμ •ν•œ ν…ŒμŠ€νŠΈ 슀크립트λ₯Ό μ§€μ •ν•˜κ³  μ‹€ν–‰ν•˜λ €λ©΄ rake test:helpers ν…ŒμŠ€νŠΈ_슀크립트_경둜 λ₯Ό μ‹€ν–‰μ‹œν‚€λ©΄ λœλ‹€.

    ν…ŒμŠ€νŠΈ 쀀비와 λ’€μ²˜λ¦¬ - setupκ³Ό teardown λ©”μ„œλ“œ

    ν…ŒμŠ€νŠΈ μŠ€ν¬λ¦½νŠΈμ—λŠ” 각각의 ν…ŒμŠ€νŠΈ λ©”μ„œλ“œκ°€ 호좜되기 μ „κ³Ό 후에 μžλ™μœΌλ‘œ ν˜ΈμΆœλ˜λŠ” μ˜ˆμ•½ λ©”μ„œλ“œκ°€ μžˆλ‹€. ν…ŒμŠ€νŠΈ 슀크립트의 λΆ€λͺ¨ 클래슀 ActiveSupport::TestCase에 μ •μ˜λ˜μ–΄ μžˆλŠ” λ©”μ„œλ“œμ΄λ―€λ‘œ μ˜€λ²„λΌμ΄λ“œν•΄μ„œ μ‚¬μš©ν•œλ‹€.

    각각 무슨 역할을 ν•˜λŠ”μ§€ μ΄λ¦„μ—μ„œ λ”± 감이 μ˜¨λ‹€.

    • setup: 각 ν…ŒμŠ€νŠΈ λ©”μ„œλ“œκ°€ 호좜되기 전에 μ‹€ν–‰(μ‚¬μš©ν•  λ¦¬μ†ŒμŠ€ μ΄ˆκΈ°ν™”)

    • teardown: 각 ν…ŒμŠ€νŠΈ λ©”μ„œλ“œκ°€ 호좜된 이후에 μ‹€ν–‰(μ‚¬μš©ν•œ λ¦¬μ†ŒμŠ€ λ’€μ²˜λ¦¬)

    μ•„λž˜μ²˜λŸΌ μ“°λ©΄ λœλ‹€.

    def setup
      @b = books(:jslib)
    end
    ​
    def teardown
      @b = nil
    end
    ​
    test "where method test" do
      ...
        assert_equal @b.isbn, result.isbn, 'isbn column is wrong'
        assert_equal @b.published, result.published, 'published column is wrong'
    end

    참고둜 λ°μ΄ν„°λ² μ΄μŠ€ ν”½μŠ€μ²˜λ₯Ό μ½λŠ” 것과 μ œκ±°λŠ” Railsκ°€ μžλ™μ μœΌλ‘œ μ²˜λ¦¬ν•˜λ―€λ‘œ setup λ©”μ„œλ“œμ—μ„œ λ”°λ‘œ μ‹€ν–‰ν•΄μ£Όμ§€ μ•Šμ•„λ„ λœλ‹€.

    Functional ν…ŒμŠ€νŠΈ

    Functional ν…ŒμŠ€νŠΈ(κΈ°λŠ₯ ν…ŒμŠ€νŠΈ)λŠ” 컨트둀러(μ•‘μ…˜)의 λ™μž‘ λ˜λŠ” ν…œν”Œλ¦Ώμ˜ 좜λ ₯을 ν™•μΈν•˜κΈ° μœ„ν•œ ν…ŒμŠ€νŠΈμ΄λ‹€. Functional ν…ŒμŠ€νŠΈμ—μ„œλŠ” λΈŒλΌμš°μ €μ²˜λŸΌ HTTP μš”μ²­μ„ μœ μ‚¬μ μœΌλ‘œ μž‘μ„±ν•˜λŠ” κ²ƒμœΌλ‘œ μ•‘μ…˜ λ©”μ„œλ“œλ₯Ό μ‹€ν–‰ν•˜κ³  κ·Έ 결과둜 HTTP μƒνƒœ μ½”λ“œ, ν…œν”Œλ¦Ώ λ³€μˆ˜ λ˜λŠ” μ΅œμ’…μ μΈ 좜λ ₯ ꡬ쑰 등을 ν™•μΈν•œλ‹€. λ˜ν•œ, 라우트 μ •μ˜μ˜ μœ νš¨μ„±μ„ ν™•μΈν•˜λŠ” 것도 Functional ν…ŒμŠ€νŠΈμ˜ 역할이닀.

    컨트둀러 test λ©”μ„œλ“œ μž‘μ„±

    /test/controllers 폴더 내뢀에 xxx_controller_test.rb에 test λ©”μ„œλ“œλ‘œ ν…ŒμŠ€νŠΈλ₯Ό μž‘μ„±ν•œλ‹€. μ•„λž˜λŠ” μ˜ˆμ‹œ.

    require "test_helper"
    ​
    class HelloControllerTest < ActionDispatch::IntegrationTest
      test "list action" do
        get :list
        assert_equal 10, assigns(:books).length, 'found rows is wrong.'
        assert_response :success, 'list action failed.'
        assert_template 'hello/list'
      end
    end

    ν…ŒμŠ€νŠΈ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜λŠ” 것 μžμ²΄λŠ” Unit ν…ŒμŠ€νŠΈμ™€ κ°™μ§€λ§Œ, λͺ‡ κ°€μ§€ Functional ν…ŒμŠ€νŠΈλ§Œμ˜ ν¬μΈνŠΈκ°€ μžˆλ‹€.

    get λ©”μ„œλ“œλ‘œ μš”μ²­ 생성

    μ•„λž˜λŠ” 맀개 λ³€μˆ˜ 정보λ₯Ό ν•¨κ»˜ μ „λ‹¬ν•˜λŠ” 예제!

    get :show, { id: 108 }

    Functional ν…ŒμŠ€νŠΈμ—μ„œ μ΄μš©ν•  수 μžˆλŠ” μ˜ˆμ•½ λ³€μˆ˜

    Functional ν…ŒμŠ€νŠΈμ—μ„œλŠ” get, post λ“±μ˜ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•œ 후에 μ•„λž˜ μ˜ˆμ•½ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλ‹€.

    λΆ„λ₯˜

    λ³€μˆ˜ 이름

    μ„€λͺ…

    객체

    @controller

    μš”μ²­μ„ μ²˜λ¦¬ν•œ 컨트둀러 클래슀

    객체

    @request

    μš”μ²­ 객체

    객체

    @response

    응닡 객체

    ν•΄μ‹œ

    assigns(:key), assigns['key']

    λ·°μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” ν…œν”Œλ¦Ώ λ³€μˆ˜

    ν•΄μ‹œ

    cookies[:key]

    μΏ ν‚€ 정보

    ν•΄μ‹œ

    flash[:key]

    ν”Œλž˜μ‹œ 정보

    ν•΄μ‹œ

    session[:key]

    μ„Έμ…˜ 정보

    Functional ν…ŒμŠ€νŠΈμ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” assert_xxxx λ©”μ„œλ“œ

    Unit ν…ŒμŠ€νŠΈμ—μ„œ 썼던 Assertion λ©”μ„œλ“œ 말고도 Functional ν…ŒμŠ€νŠΈμ—μ„œ μΆ”κ°€λ‘œ μ“Έ 수 μžˆλŠ” Assertionκ°€ μžˆλ‹€. μ€‘μš”ν•œ 것 λͺ‡ 개λ₯Ό μ •λ¦¬ν•΄λ³΄μžλ©΄ μ•„λž˜μ™€ κ°™λ‹€.

    1. assert_difference λ©”μ„œλ“œ: 처리 ν›„ μƒνƒœ λ³€ν™” 확인

    2. assert_generates λ©”μ„œλ“œ: λΌμš°νŒ… λ™μž‘ 확인

    3. assert_select λ©”μ„œλ“œ: ν…œν”Œλ¦Ώ 좜λ ₯ κ²°κ³Ό 확인

    Integration ν…ŒμŠ€νŠΈ

    Integration ν…ŒμŠ€νŠΈ(톡합 ν…ŒμŠ€νŠΈ)λŠ” μ—¬λŸ¬ 개의 컨트둀러λ₯Ό λ„˜λ‚˜λ“€λ©° μ‹€μ œ μ‚¬μš©μžμ˜ 행동을 λͺ¨λ°©ν•  λ•Œ μ‚¬μš©ν•œλ‹€.

    예λ₯Ό λ“€μ–΄ μ±…μ—μ„œ κ΅¬ν˜„ν–ˆλ˜ 둜그인 κΈ°λŠ₯의 경우 μ•„λž˜ 절차λ₯Ό λ”°λ₯Έλ‹€. Integration ν…ŒμŠ€νŠΈλ‘œ 이런 단계적인 처리λ₯Ό μ‹€μ œλ‘œ λͺ¨λ°©ν•΄μ„œ 각각의 λ‹¨κ³„μ—μ„œ μ œλŒ€λ‘œ 된 μ²˜λ¦¬κ°€ μ΄λ£¨μ–΄μ§€λŠ”μ§€λ₯Ό 확인할 수 μžˆλ‹€.

    1. hello#view μ•‘μ…˜μ— μ ‘κ·Ό

    2. 미인증 μƒνƒœμ΄λ―€λ‘œ, login#index μ•‘μ…˜(둜그인 νŽ˜μ΄μ§€)둜 λ¦¬λ‹€μ΄λ ‰νŠΈ

    3. 둜그인 νŽ˜μ΄μ§€μ—μ„œ μ‚¬μš©μž 이름과 λΉ„λ°€λ²ˆν˜Έλ₯Ό μž…λ ₯ν•˜κ³  인증 처리

    4. login#auth μ•‘μ…˜μ—μ„œ 인증 μ²˜λ¦¬κ°€ μ™„λ£Œλ˜λ©΄ hello#view μ•‘μ…˜μœΌλ‘œ λ¦¬λ‹€μ΄λ ‰νŠΈ

    ν…ŒμŠ€νŠΈ 슀크립트 μ˜ˆμ‹œ

    1. ν…ŒμŠ€νŠΈ 슀크립트 생성

      Integration ν…ŒμŠ€νŠΈλŠ” 직접 rails generate integration_test xxxxx λͺ…λ Ήμ–΄λ‘œ μƒμ„±ν•΄μ€˜μ•Όν•œλ‹€.

      rails generate integration_test admin_login
      # test/integration/admin_login_test.rb κ°€ 생성됨.
    2. ν…ŒμŠ€νŠΈ 슀크립트 μž‘μ„± μœ„μ— μ˜ˆμ‹œλ‘œ 적은 둜그인 처리λ₯Ό ν™•μΈν•˜λŠ” μ½”λ“œ μ˜ˆμ‹œλŠ” μ•„λž˜μ™€ κ°™λ‹€.

      require 'test_helper'
      class AdminLoginTest < ActionDispatch::IntegrationTest
        test "login test" do
          get '/hello/view'
          assert_response :redirect
          assert_redirected_to controller: :login, action: :index
          assert_equal '/hello/view', flash[:referer]
          
          follow_redirect!
          assert_response :success
          assert_equal '/hello/view', flash[:referer]
          
          post '/login/auth', { username: 'arint', password: '12345', referer: '/hello/view' }
          assert_response :redirect
          assert_redirected_to controller: :hello, action: :view
          assert_equal users(:arint).id, session[:usr]
          
          follow_redirect!
          assert_response :success
        end
      end 

      쀑간 쀑간에 μžˆλŠ” follow_redirect! λŠ” 응닡에 μžˆλŠ” λ¦¬λ‹€μ΄λ ‰νŠΈ λŒ€μƒμœΌλ‘œ λ‹€μ‹œ μš”μ²­ν•˜λŠ” κΈ°λŠ₯이닀. 미인증 μƒνƒœμ˜ μ‚¬μš©μžκ°€ /hello/view에 μ ‘κ·Όν•˜λ©΄ 둜그인 νŽ˜μ΄μ§€λ‘œ λ¦¬λ‹€μ΄λ ‰νŠΈν•˜λΌλŠ” 응닡을 λ°›κ²Œ 될텐데, 이 λ•Œ 받은 λ¦¬λ‹€μ΄λ ‰νŠΈ λŒ€μƒμœΌλ‘œ μ΄λ™ν•˜λŠ” 것을 λͺ¨λ°©ν•˜λŠ” 것이닀.

    3. ν…ŒμŠ€νŠΈ 슀크립트 μ‹€ν–‰

      rake test:integration λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜λ©΄ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰μ‹œν‚¬ 수 μžˆλ‹€.

ν•™μŠ΅ λ‚΄μš©μ— λŒ€ν•œ 개인적인 총평

RESTful, Test λ‘˜ λͺ¨λ‘ 취업곡고λ₯Ό 보면 자주 λ§Œλ‚  수 μžˆλŠ” ν‚€μ›Œλ“œμž…λ‹ˆλ‹€. Railsλ₯Ό ν•™μŠ΅ν•˜λŠ” κ³Όμ •μ—μ„œ 이 λ‘˜μ„ μ•½κ°„μ΄λ‚˜λ§ˆ λ§›λ³Ό 수 μžˆλŠ”κ²Œ μ’‹λ„€μš”. Railsλ₯Ό ν•™μŠ΅ν•  λ•Œλ§ˆλ‹€ nest.jsλ‚˜ spring ν•™μŠ΅μ— μ‹œκ°„μ„ μ“°κ³  μ‹Άλ‹€λŠ” 생각이 μ™•μ™•λ“€κΈ΄ ν•˜μ§€λ§Œ, 이런 μ‹μœΌλ‘œ 'λ°±μ—”λ“œ'에 ν•„μš”ν•œ κ°œλ…κ³Ό κΈ°μˆ μ„ ν™•μ‹€νžˆ ν•™μŠ΅ν•΄λ²„λ¦¬λŠ” 기회둜 μ‚Όμ•„μ•Όκ² μŠ΅λ‹ˆλ‹€.

λ‹€μŒ ν•™μŠ΅ κ³„νš

  • λ£¨λΉ„μ˜¨λ ˆμΌμ¦ˆ ν΄λΌμ΄μ–ΈνŠΈλ‹¨ ν›‘κΈ°

Previous2021-01-05(Tue)Next2021-01-01(Fri)

Last updated 4 years ago

Was this helpful?

RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ •μ˜ν•  λ•ŒλŠ” routes.rbμ—μ„œ λ₯Ό ν˜ΈμΆœν•œλ‹€.

resources λ©”μ„œλ“œκ°€ μ—¬λŸ¬ 개의 λ¦¬μ†ŒμŠ€λ₯Ό κ΄€λ¦¬ν•˜λŠ” RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό μƒμ„±ν•œλ‹€λ©΄, λŠ” ν•˜λ‚˜μ˜ λ¦¬μ†ŒμŠ€λ₯Ό κ΄€λ¦¬ν•˜λŠ” RESTful μΈν„°νŽ˜μ΄μŠ€λ₯Ό 생성할 수 μžˆλ‹€.

RESTful ν•˜μ§€ μ•Šμ€ 라우트λ₯Ό μ •μ˜ν•  λ•ŒλŠ” λ₯Ό μ‚¬μš©ν•œλ‹€.

ν…ŒμŠ€νŠΈ ν”„λ ˆμž„μ›Œν¬λ‘œλŠ” RSpec, minitest, Test::Unit 등이 μžˆλ‹€.

/test/models 내뢀에 μƒμ„±λœ μŠ€ν¬λ¦½νŠΈμ— λ₯Ό μ΄μš©ν•΄μ„œ ν…ŒμŠ€νŠΈ ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄μ£Όμž. 이 λ•Œ testλ©”μ„œλ“œλ„ λ‚΄λΆ€μ μœΌλ‘œ test_xxxx λ©”μ„œλ“œλ₯Ό μƒμ„±ν•˜λŠ” κ²ƒλΏμ΄λ―€λ‘œ test_둜 μ‹œμž‘ν•˜λŠ” λ©”μ„œλ“œλ₯Ό 직접 μ •μ˜ν•΄λ„ 상관없닀.

Functional ν…ŒμŠ€νŠΈμ—μ„œλŠ” 일단 컨트둀러λ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•΄ 둜 HTTP μš”μ²­μ„ μƒμ„±ν•œλ‹€.

resources λ©”μ„œλ“œ
resource λ©”μ„œλ“œ
match λ©”μ„œλ“œ
μ°Έκ³ 
test λ©”μ„œλ“œ
get λ©”μ„œλ“œ