일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
- contravariant
- 공변
- Heuristic Watermark
- Perfect Watermarks
- Heuristic Watermarks
- Hadoop
- covariant
- Generic
- Perfect Watermark
- java
- MapReduce
- kotlin
- ingestion time
- Coroutine
- 불공변
- processing time
- Generics
- coroutines
- apache flink
- Stream
- 가변성
- HDFS
- watermark
- lambda
- event time
- flink watermark
- flink watermarks
- flink
- watermarks
- Today
- Total
mm Home
Rails 기본 본문
루비온레일즈 가이드 홈페이지 내용을 공부하면서 정리한 내용이다. (http://rubykr.github.io/rails_guides/)
Rails 철학
Rails 기본 구조
IDE에서 rails 프로젝트를 신규 생성하면 아래와 같은 구조를 가지는 프로젝트가 생성된다. (rails new 명령어를 이용해 생성됨)
gem : 루비에서 지원하는 패키지 시스템 (루비 라이브러리)
Scaffold : 특정 Model을 생성하면서 CRUD 기반의 View, Controller를 한 번에 만들어주는 명령어
파일/폴더 | 목적 |
---|---|
app/ | 애플리케이션 컴포넌트를 담고 있다. 뷰, 모델, 컨트롤러 |
config/ | rails 어플리케이션의 설정(라우팅, 데이터베이스 등) |
db/ | RDB를 접근하는 모델 & RDB 관리 스크립트 & 마이그레이션 내용 |
Gemfile Gemfile.lock | gem의 의존성을 관리하는 파일 (bundler 에서 사용) |
lib/ | 애플리케이션에서 사용하는 확장 모듈 |
log/ | 애플리케이션의 로그 |
public/ | 이 폴더의 밑에 있는 파일들은 외부(인터넷)에서 직접 참조할 수 있다. 정적인 파일이나 컴파일된 애셋들이 위치한다. |
Rakefile | Makefile과 비슷함. rails 코드를 빌드, 패키징, 테스트하는데 쓰인다. |
test/ | Unit 테스트 관련 |
tmp/ | 임시 파일 폴더 |
vendor/ | 3rd party 벤더들이 제공하는 외부 라이브러리 디렉토리 |
Scaffold : 특정 Model을 생성하면서 CRUD 기반의 View, Controller를 한 번에 만들어주는 명령어
- 이 명령어 한 번에 소규모 게시판은 바로 만들어진다 (물론 view의 레이아웃이나 CSS, Controller의 API 호출이나 세부적인 사항은 개발자가 직접 해야하긴 함)
$ rails generate scaffold Post title:string author:string contents:text
scaffold generate 는 아래와 각 디렉토리에 15개의 파일을 생성한다
파일 | 목적 |
---|---|
db/migrate/20100207214725_create_posts.rb | 데이터베이스에 ‘posts’ 테이블 생성하는 마이그레이션 (여러분의 파일 이름은, 다른 타임 스템프 값을 가지고 있습니다.) |
app/models/post.rb | Post 모델 |
test/fixtures/posts.yml | 테스트를 위한 더미(Dummy) posts |
app/controllers/posts_controller.rb | Posts 컨트롤러 |
app/views/posts/index.html.erb | 모든 posts 를 출력하는 index 뷰 |
app/views/posts/edit.html.erb | 존재하는 post 를 수정하는 edit 뷰 |
app/views/posts/show.html.erb | 단일 post를 보여주는 show 뷰 |
app/views/posts/new.html.erb | 새로운 post 를 만들기 위한 new 뷰 |
app/views/posts/_form.html.erb | post 를 수정하거나 새로 만드는데 사용되는 폼(form)을 저장하는 조각(partial) 파일 |
app/helpers/posts_helper.rb | post 뷰를 위한 헬퍼(Helper) 함수를 위한 파일 |
test/unit/post_test.rb | posts 모델을 위한 유닛 테스트 파일 |
test/functional/posts_controller_test.rb | posts 컨트롤러를 위한 기능 테스트 파일 |
test/unit/helpers/posts_helper_test.rb | posts 헬퍼(Helper)를 위한 유닛 테스트 파일 |
config/routes.rb | posts 를 위한 라우팅 정보를 담은 수정된 라우팅 파일 |
public/stylesheets/scaffold.css | 발판(Scaffold) 뷰를 좀 더 미려하게 만드는 CSS 파일 |
Routing
rails 의 라우터는 요청받은 URL을 인식하여 적절한 컨트롤러의 액션에 매핑한다. 라우터는 URL을 직접 매핑하거나 관습을 통한 자동 매핑도 지원한다.
http://guides.rorlab.org/routing.html
직접 매핑
GET /patients/17
위 HTTP 요청에 대하여 직접 매핑은 아래와 같이 할 수 있다
get
'/patients/:id'
, to:
'patients#show'
이 요청은 patients 컨트롤러의 show 액션에 할당되며, params에는 { id: '17' } 해시가 포함된다
리소스 기반 자동 라우팅 : Rails 기본
리소스 기반의 라우팅(이하 리소스 라우팅)을 사용하는 것으로 공통 라우팅을 간단하게 선언할 수 있다. RESTful한 라우팅을 선언하는 것으로 컨트롤러의 index, show, new, edit, create, update, destroy 액션을 별도로 선언하지 않고 한줄로 완료할 수 있다.resources
:photos
라고 라우팅 설정을 했다고 가정하면
HTTP 메서드경로컨트롤러#액션목적GET /photos photos#index 모든 사진 목록을 표시 GET /photos/new photos#new 사진을 1개 생성하기 위한 HTML 양식을 반환 POST /photos photos#create 사진을 1개 생성 GET /photos/:id photos#show 특정 사진을 보여줌 GET /photos/:id/edit photos#edit 사진 편집용의 HTML 양식을 반환 PATCH/PUT /photos/:id photos#update 특정 사진을 갱신 DELETE /photos/:id photos#destroy 특정 사진을 삭제 위와 같은 기본 설정이 관습에 의해 생성된다.
자동 라우팅을 통해 URL용 헬퍼가 지원된다
예) resources :photos 를 통해 예를 들어보면,helper path (*_path Helper)실제 pathphots_path /photos new_photo_path /photos/new edit_photo_path(:id) /photos/:id/edit photo_path(:id) /photos/:id 복수의 리소스를 동시에 정의할 수 있다
resources
:photos
,
:books
,
:videos
위의 설정은 아래의 설정과 동일하다
resources
:photos
resources
:books
resources
:videos
단수형 리소스
상황에 따라서 ID 참조가 필요없는 리소스가 필요할 때가 있다. 예를 들어 /profile 에서는 항상 현재 로그인한 유저의 정보를 보여주고, 다른 사용자의 id를 참조할 필요가 없다.
이런 경우는 아래와 같이 라우팅 설정을 할 수 있다 (단일 설정)get
'profile'
, to:
'users#show'
단수형에 대한 RESTful 한 리소스 설정은 아래와 같다. (resources → resource)resource
:geocoder
단수형에 대해서는 6개의 라우팅을 생성한다
HTTP 메서드경로컨트롤러#액션목적GET /geocoder/new geocoders#new geocoder 작성용 양식을 반환 POST /geocoder geocoders#create geocoder를 생성 GET /geocoder geocoders#show 하나뿐인 geocoder 리소스를 표시 GET /geocoder/edit geocoders#edit geocoder 수정용 HTML 양식을 반환 PATCH/PUT /geocoder geocoders#update 하나뿐인 geocoder 리소스를 갱신 DELETE /geocoder geocoders#destroy geocoder 리소스를 삭제 *단수형 리소스 컨트롤러와 복수형 리소스 컨트롤러는 같은 컨트롤러에 할당된다. ( resources :photo 와 resource :photo 는 같은 컨트롤러 PhotosController에 할당된다)
단수형 헬퍼 메소드는 아래와 같이 3개가 생성된다helper path (*_path Helper)실제 pathnew_geicider_path /geocoder/new edit_geocoder_path /geocoder/edit geocoder_path /geocoder 네임스페이스를 통한 라우팅
다수의 관리용 컨트롤러들을 묶어서 특정 라우팅 path에 두도록 하고 싶을 것이다. (ex. admin/geocoder/~, admin/photos/~, admin/books/~)
이런 경우는 아래와 같이 네임스페이스 설정을 통해 특정 path를 강제할 수 있다namespace
:admin
do
resources
:posts
,
:comments
end
중첩된 리소스
아래와 같은 모델이 있다고 가정해보자.class
Magazine < ActiveRecord::Base
has_many
:ads
end
class
Ad < ActiveRecord::Base
belongs_to
:magazine
end
매거진 내에는 다수의 Ad가 존재하게 된다. 위와 같이 리소스가 중첩되는 경우에는 아래와 같이 라우팅을 선언할 수 있다
resources
:magazines
do
resources
:ads
end
HTTP 메서드경로컨트롤러#액션목적GET /magazines/:magazine_id/ads ads#index 잡지 1권에 포함되는 광고를 모두 표시한다. GET /magazines/:magazine_id/ads/new ads#new 어떤 잡지에 광고를 추가할 수 있는 HTML 양식을 반환한다. POST /magazines/:magazine_id/ads ads#create 어떤 잡지 1권에 잡지용의 광고를 하나 추가한다. GET /magazines/:magazine_id/ads/:id ads#show 어떤 잡지 1권에 포함되는 광고를 하나 보여준다. GET /magazines/:magazine_id/ads/:id/edit ads#edit 어떤 잡지 1권에 포함되는 광고 하나를 수정할 수 있는 HTML 양식을 반환한다. PATCH/PUT /magazines/:magazine_id/ads/:id ads#update 어떤 잡지 1권에 포함되는 광고 하나를 갱신한다. DELETE /magazines/:magazine_id/ads/:id ads#destroy 어떤 잡지 한권에 포함되는 광고를 하나 삭제한다. 최소한의 정보로 리소스를 표현하는 설정도 가능하다
resources
:posts
do
resources
:comments
, only: [
:index
,
:new
,
:create
]
end
resources
:comments
, only: [
:show
,
:edit
,
:update
,
:destroy
]
Resourceful하지 않은 라우팅
Resourcefulg하지 않은 라우팅이 필요할 경우가 있다. 이런 경우 아래와 같이 설정하면 된다.get
':controller(/:action(/:id))'
:controller → controller 이름
:action → 컨트롤러에 존재하는 액션의 이름과 매칭 (메소드)
:id → ID
필수가 아닌 항목에 대해서는 () 로 표현. action, id- 쿼리 문자열
get
':controller/:action/:id'
/photos/show/1?user_id=2
위의 라우팅에서 들어오는 쿼리 문자열은 아래와 같이 설정 된다.params
는{ controller: 'photos', action: 'show', id: '1', user_id: '2' }
가 된다
- 쿼리 문자열
기타 자세한 사항은 레일즈 문서 참고
Controller
컨트롤러는 요청을 해석하고 적절한 응답을 돌려줄 책임이 있다. Rails에서는 라우팅한 결과에 따라 컨트롤러가 모델과 뷰의 사이를 중개한다.
http://guides.rorlab.org/action_controller_overview.html
- 명명 규칙
컨트롤러의 이름은 기본적으로 복수형을 사용한다. 반드시 지켜야 하는 사항은 아니다. 다만 관습에 의한 설정을 사용하기 위해서는 복수형을 사용해야 한다. - 메소드와 액션
애플리케이션이 클라이언트로부터 요청을 받으면 라우팅에 의해서 실행할 컨트롤러와 액션이 결정되고, Rails는 그 컨트롤러의 액션명과 동일한 이름을 가지는 메소드를 실행한다. - 매개 변수
- 쿼리 문자열
- POST 데이터
컨트롤러는 위의 두가지 매개 변수를 동일하게 params라는 해시를 통해 접근할 수 있다.
class
ClientsController < ApplicationController
# 이 액션에서는 쿼리 문자열 매개 변수가 사용됩니다.
# 전송측에서 HTTP GET 요청을 사용하기 때문입니다.
# 단 매개 변수에 접근하는 방법은 아래의 방식과 다르지 않습니다.
# 유효한 고객 목록을 얻기 위해 이 액션의 URL은 다음과 같이 되어 있습니다.
# clients: /clients?status=activated
def
index
if
params[
:status
] ==
"activated"
@clients
= Client.activated
else
@clients
= Client.inactivated
end
end
# 이 액션에서는 POST 데이터를 사용하고 있습니다.
# 이 매개 변수는 일반적으로 사용자가 전송한 HTML 폼으로부터 생성됩니다.
# 이것은 RESTful한 접근이며, URL은 "/clients"가 됩니다.
# 데이터는 URL이 아닌 요청의 body에 포함되어 전송됩니다.
def
create
@client
= Client.
new
(params[
:client
])
if
@client
.save
redirect_to
@client
else
# 아래 줄에서는 기본 랜더링 동작을 덮어씁니다.
# 기본으로는 "create" 뷰가 랜더링됩니다.
render
"new"
end
end
end
Strong parameters
컨트롤러가 받은 변수에 대해 갱신을 허가하고, 어떤 설정에 대해서는 갱신을 금지할지 명시적으로 결정하기 위함이다.
매개변수에 대해 required(필수)를 지정할 수 있으며, 400 bad request를 돌려줄 수 있다class
PeopleController < ActionController::Base
# 이 코드는 ActiveModel::ForbiddenAttributes 예외를 던집니다.
# 명시적으로 검증을 하지 않고 매개 변수를 그냥 통째로 넘기고 있기 때문입니다.
def
create
Person.create(params[
:person
])
end
# 이 코드는 매개 변수에 person이라는 키가 존재하는 경우에만 성공합니다.
# person이라는 키가 없는 경우에는 ActionController::ParameterMissing 예외를 던집니다.
# 이 예외는 ActionController::Base가 잡아 400 Bad Request로 반환합니다.
def
update
person = current_account.people.find(params[
:id
])
person.update!(person_params)
redirect_to person
end
private
# private 메소드를 사용해서 매개 변수 검증을 캡슐화합니다.
# 이를 통해 create와 update에서 같은 검증을 쉽게 재사용할 수 있습니다.
# 또한 허가할 속성을 사용자마다 다르게 만들 수도 있습니다.
def
person_params
params.require(
:person
).permit(
:name
,
:age
)
end
end
params.permit(
:id
)
params에 :id 키가 있다면 화이트리스트 검증을 통과한다.
중첩된 매개 변수에 대해서도 아래와 같이 검증할 수 있다.
params.permit(
:name
, { emails: [] },
friends: [
:name
,
{ family: [
:name
], hobbies: [] }])
- 세션
Rails에서는 세션 기능을 지원한다. 모든 방식은, 세션의 식별자를 쿠키에 보존하며 아래와 같은 클래스를 통해 지원한다.ActionDispatch::Session::CookieStore - 모든 세션을 클라이언트 측의 쿠키에 저장
ActionDispatch::Session::CacheStore - 데이터를 Rails의 캐시에 저장
ActionDispatch::Session::ActiveRecordStore - 액티브 레코드를 사용해서 데이터베이스에 저장(activerecord-session_store gem이 필요)
ActionDispatch::Session::MemCacheStore - 데이터를 memcached 클러스터에 저장(이 방식은 오래되었으므로 이보다는 CacheStore를 검토하길 권장)
- 세션 접근
컨트롤러에서 session 메소드를 사용해서 접근이 가능하다class
ApplicationController < ActionController::Base
private
# 세션에 저장되어 있는 id로 사용자를 검색합니다.
# :current_user_id는 Rails 애플리케이션에서 사용자 로그인 정보를 다루는 일반적인 방법입니다.
# 로그인하면 세션 값을 저장하고, 로그아웃 하면 세션 값을 삭제합니다.
def
current_user
@_current_user
||= session[
:current_user_id
] &&
User.find_by(id: session[
:current_user_id
])
end
end
세션을 사용하고 싶다면, 해쉬와 비슷한 방식으로 사용이 가능하다
class
LoginsController < ApplicationController
# "Create" a login, aka "log the user in"
def
create
if
user = User.authenticate(params[
:username
], params[
:password
])
# 세션에 사용자 ID를 저장하여, 다음 요청에서 사용할 수 있게 합니다.
redirect_to root_url
end
end
end
세션에서 데이터의 일부를 제거하고 싶은 경우에는 키에
nil
을 할당하면 된다.class
LoginsController < ApplicationController
# 로그인을 해제합니다(=로그아웃)
def
destroy
# 세션 id로부터 user id를 제거
@_current_user
= session[
:current_user_id
] =
nil
redirect_to root_url
end
end
- 쿠키
cookies 메소드를 통해서 쿠키에 접근할 수 있다. 세션과 비슷한 사용방법class
CommentsController < ApplicationController
def
new
# cookie에 덧글 작성자의 이름이 남아 있다면 필드에 자동으로 입력한다.
@comment
= Comment.
new
(author: cookies[
:commenter_name
])
end
def
create
@comment
= Comment.
new
(params[
:comment
])
if
@comment
.save
flash[
:notice
] =
"Thanks for your comment!"
if
params[
:remember_name
]
# 덧글 작성자의 이름을 저장
cookies[
:commenter_name
] =
@comment
.author
else
# 덧글 작성자의 이름이 쿠키에 남아있다면 삭제
cookies.delete(
:commenter_name
)
end
redirect_to
@comment
.article
else
render action:
"new"
end
end
end
세션을 삭제할 때에는 키에
nil
을 대입했지만, cookie를 삭제하는 경우에는cookies.delete(:key)
를 사용해야 한다.
필터
액션의 직전(before), 직후(after), 또는 그 둘다(around)에 실행되는 메소드이다. 필터는 상속이 가능하기 때문에ApplicationController
에 필터를 설정하면 애플리케이션의 모든 컨트롤러에 적용이 된다.class
ApplicationController < ActionController::Base
before_action
:require_login
private
def
require_login
unless
logged_in?
flash[
:error
] =
"You must be logged in to access this section"
redirect_to new_login_url
# 처리를 중지한다
end
end
end
around 사용법class
ChangesController < ApplicationController
around_action
:wrap_in_transaction
, only:
:show
private
def
wrap_in_transaction
ActiveRecord::Base.transaction
do
begin
yield
ensure
raise
ActiveRecord::Rollback
end
end
end
end
Request 객체
Request 객체의 주요 속성
request
의 속성목적host 요청에 사용된 호스트 이름 domain(n=2) 호스트의 이름(TLD)의 우측으로부터 n
번째 세그먼트format 클라이언트로부터 요청받은 Content-Type method 요청에서 사용된 HTTP 메소드 get?, post?, patch?, put?, delete?, head? HTTP메소드가 GET/POST/PATCH/PUT/DELETE/HEAD 중 각각 맞는 메소드에 해당하는 경우 true를 돌려줌 headers 요청에 포함되어있는 헤더를 포함하는 해시를 돌려줌 port 요청에 사용된 포트 번호(정수) protocol 사용된 프로토콜을 포함한 주소 문자열을 돌려줌(예를 들어, "http://....." 이런 형태) query_string URL에서 사용된 쿼리 문자열("?" 뒷 부분) remote_ip 클라이언트의 ip 주소 url 요청에서 사용된 URL 전체 Response 객체
Response 객체를 직접 사용할 일은 거의 없다.response
의 속성목적body 클라이언트에 돌려줄 데이터의 문자열. 대부분의 경우 HTML status 응답의 HTTP 상태 코드(200 OK, 404 file not found 등) location 리다이렉션을 할 URL content_type 응답의 Content-Type charset 응답에 사용될 문자셋. 기본은 "utf-8" headers 응답에 사용될 헤더들
Layout & Rendering
Controller - View - Model 사이에서 일어나는 동작에 대한 설명이다.
http://guides.rorlab.org/layouts_and_rendering.html
- 응답 생성
HTTP 응답의 생성방법은 3가지가 있다
1. render 호출해서 브라우저에 돌려줄 응답 생성
2. redirect_to 호출해서 HTTP 리다이렉트 코드를 브라우저에 돌려줌
3. head를 호출해서 HTTP 헤더로만 구성된 응답을 생성 기본 출력
기본 설정이 되어있다는 가정 하에... (라우팅 설정, view 페이지(index.html.erb))
class
BooksController < ApplicationController
def
index
@books
= Book.all
end
end
관습에 의해 렌더링에 대한 설정 없이도 위의 코드는 HTTP 응답을 내려준다.
여기서의 원칙은 액션의 마지막 부분에서 명시적인 렌더링 지시가 없을 경우에는 컨트롤러가 사용가능한 뷰 목록의 경로로부터 {action명}.html.erb 의 뷰 템플릿을 찾아 사용한다.
뷰(index.html.erb) 에서는 아래와 같이 작성이 가능하다.실제 렌더링 작업은 ActionView::TemplateHandlers의 서브클래스에서 실행된다.
- render 사용하기
대부분의 경우,ActionController::Base#render
메소드가 브라우저에 애플리케이션의 내용을 출력을 출력하는 일을 담당한다.render
메소드는 다양한 방법으로 커스터마이즈할 수 있다. Rails 템플릿의 기본 뷰를 출력할 수도 있고, 특정 템플릿, 파일, 인라인 코드를 지정해서 출력하거나, 아무것도 출력하지 않는 것도 가능하다아무것도 출력하지 않을 경우
render nothing:
true
Action View 출력
기본 설정과 다른 템플릿을 지정이 가능하다.
def
update
@book
= Book.find(params[
:id
])
if
@book
.update(book_params)
redirect_to(
@book
)
else
render
"edit" ##문자열 대신 심볼도 가능
end
end
다른 컨트롤러의 템플릿 사용
render
"products/show"
Rails는 경로에 / 가 포함되어있으면 다른 컨트롤러에 속해있는 템플릿이라고 인식한다. (Rails 2.2 이하에서는 template: 키워드가 필수)
텍스트 출력
render plain:
"OK"
plain 옵션을 통해 문자열을 그대로 브라우저에 전송할 수 있다
*기본적으로 plain 옵션은 레이아웃을 무시하고 렌더링된다. 레이아웃을 포함해서 렌더링 하고 싶은 경우에는 layout: true 옵션을 추가하면 된다.- JSON 렌더링
json 옵션을 추가하면 to_json 메소드를 추가하지 않아도 된다.
- render 옵션
- :content_type
Rails의 기본 출력 MIME content-type은 text/html 이다. (JSON, xml 제외) content-type을 변경하고 싶은 경우에 사용한다. - :layout
layout 옵션을 통해 현재의 액션에서 특정 파일을 레이아웃으로 사용할 수 있다 - location
HTTP의 Location 헤더를 설정할 수 있다 - status
HTTP 상태코드를 변경할 수 있다
- :content_type
- layout 사용
Rails는 레이아웃이 app/views/layouts에 있는지 확인한다. (ex. PhotosController 클래스의 액션을 렌더링할 경우, photos.html.erb가 있는지를 확인)
Rails는 컨트롤러나 액션별로 특정 레이아웃을 더 정확하게 지정할 수 있다. 컨트롤러 레이아웃 지정
class
ProductsController < ApplicationController
layout
"inventory"
#...
end
아래와 같이 ApplicationController에 레이아웃 설정을 한다면, 어플리케이션 전체에 걸친 기본 레이아웃을 설정하게 된다.
실행시에 레이아웃을 지정하고 싶다면 아래와 같이 심볼을 이용하면 된다.이외에도 메서드명을 이용하여 조건부로 레이아웃을 사용이 가능하며, 컨트롤러 상속시에 레이아웃 설정도 그대로 상속된다. (자세한 내용은 공식 문서 참고)
redirect_to 사용
redirect_to photos_url
redirect_to action: :index
본문이 없는 응답
body가 없는 응답을 전송할 수 있다. HTTP 상태 코드를 표현하는 심볼을 넘길 수 있다.head
:bad_request
head
:created
, location: photo_path(
@photo
)
- 레이아웃 구성
레이아웃을 구성하기 위해 3가지 도구를 사용한다.- Asset tags
- yield와 content_for
- Partials
Asset Tags
피드, JavaScript, 스타일시트, 이미지, 동영상과 음성의 링크를 위한 HTML 생성용으로 아래 6개의 애셋 태그 헬퍼를 사용 할 수 있다. (상세 내용은 문서를 참고)
auto_discovery_link_tag
javascript_include_tag
stylesheet_link_tag
image_tag
video_tag
audio_tag
yield
레이아웃에서 뷰에 삽입해야할 장소를 지정할 때 사용한다.
기본적인 사용법으로 yield는 하나만 사용하고, 지정된 뷰의 컨텐츠 전체를 그 위치에 삽입한다.
아래와 같이 yield를 여러 곳에서 호출하는 레이아웃 작성도 가능하다<
html
>
<
head
>
<%=
yield
:head
%>
</
head
>
<
body
>
<%=
yield
%>
</
body
>
</
html
>
(뷰의 메인 본문은 이름이 없는 yield에 삽입)
content_for
content_for
메소드를 사용하면, 컨텐츠를 이름이 붙은yield
블록으로 호출해 레이아웃에 삽입할 수 있다.<%
content_for
:head
do
%>
<
title
>A simple page</
title
>
<%
end
%>
<
p
>Hello, Rails!</
p
>
content_for 메소드는 레이아웃이 'sidebar', 'footer'같은 영역으로 분리되어있고, 각각 다른 컨텐츠를 삽입하고 싶은 상황에서 사용한다.
결과는 아래와 같다.<
html
>
<
head
>
<
title
>A simple page</
title
>
</
head
>
<
body
>
<
p
>Hello, Rails!</
p
>
</
body
>
</
html
>
Partial
위와는 다른 방법으로 렌더링을 편하게 만들기 위함이다.
뷰 내에서 render 메서도를 호출해서 사용할 수 있다.<%= render
"menu"
%>
예시
users/index.html.erb<%=
render
"shared/search_filters"
, search:
@q
do
|f|
%>
<
p
>
Name contains:
<%=
f.text_field
:name_contains
%>
</
p
>
<%
end
%>
roles/index.html.erb
<%=
render
"shared/search_filters"
, search:
@q
do
|f|
%>
<
p
>
Title contains:
<%=
f.text_field
:title_contains
%>
</
p
>
<%
end
%>
shared/_search_filters.html.erb
<%=
form_for(
@q
)
do
|f|
%>
<
h1
>Search form:</
h1
>
<
fieldset
>
<%=
yield
f
%>
</
fieldset
>
<
p
>
<%=
f.submit
"Search"
%>
</
p
>
<%
end
%>
뷰 템플릿에 존재하는 이 코드는 그 장소(디렉토리)에서 _menu.html.erb라는 이름의 파일을 렌더링한다. 관습에 의해 파샬 파일명은 항상 언더스코어로 시작된다.
*모든 페이지에서 공유되는 컨텐츠라면 파셜을 레이아웃에서 직접 사용해도 좋다. 다만, 파샬 파일을 레이아웃 디렉토리에 둘 수 없다.
지역 변수 넘겨주기
<
h1
>New zone</
h1
>
<%=
render partial:
"form"
, locals: {zone:
@zone
}
%>
모델 객체를 파샬로 렌더링하기
<%=
render
@customer
%>
위의 렌더링 설정은 _customer.html.erb를 통해 렌더링 될 것이다.
컬렉션 렌더링하기
<
h1
>Products</
h1
>
<%=
render partial:
"product"
, collection:
@products
%>
_product.html.erb
위의 렝더링 설정은 아래와 같이 줄여 쓸 수 있다. (파일명이 _product.html.erb 똑같다면)<
h1
>Products</
h1
>
<%=
render
@products
%>
기타 자세한 사항은 레일즈 문서 참고
Rails 커맨드
Rails를 사용하면서 중요한 명령어가 몇가지 있다.
- rails console
- rails server
- bin/rails
- rails generate
- rails dbconsole
- rails new app_name
rails new : 새로운 rails 어플리케이션을 생성하는 방법
rails server : rails 에 포함되어있는 Puma라는 웹서버가 실행된다. 어플리케이션 서버를 띄울 때 사용한다.
-e 로 environment 설정을, -p로 포트설정을 할 수 있다.
rails generate : generate 명령으로 템플릿을 사용하여 다양한 코드를 생성할 수 있다. boilerplate code를 작성할 필요가 없어진다.
- controller
Usage: rails generate controller NAME [action action] [options]
컨트롤러, 뷰 파일, 테스트 파일, 뷰 헬퍼, JavaScript, CSS 파일을 자동 생성해준다. - model
Usage: rails generate model NAME [field[:type][:index] field[:type]
scaffold 로 모델, 모델을 위한 마이그레이션, 컨트롤러, 뷰, 테스트 코드 를 모두 포함하여 생성이 가능하다.
scaffold로 생성하는 경우, 제너레이터는 모델, 컨트롤러, 헬퍼, 레이아웃, 기능 테스트, 유닛 테스트, 스타일시트용의 데이터가 존재하는지를 체크하고, 뷰, 컨트롤러, 모델, 마이그레이션을 생성하고, 이 리소스를 가리키는 라우팅을 추가하고 마지막으로 이 모든 것을 위한 테스트를 생성한다
그리고 migrate를 실행하여 마이그레이션을 적용해야 한다. (테이블 변경점을 적용)
$ rails db:migrate
rails console : 커맨드라인을 통해 Rails 어플리케이션을 직접 다룰 수 있다. 사용법은 IRB와 동일
rails dbconsole : 적절한 DBMS 를 찾고, DB 커맨드라인을 실행한다. (SQL)
rails destroy : generate 와 반대. 제너레이터 명령이 무엇을 실행했는지 확인하고, 그 이전 상태로 되돌려준다.
기타 자세한 내용은 문서를 참고.
Error handling
begin/rescue block
begin
do_something
rescue
handle_exception
end
Around filter
class
ApplicationController < ActionController::Base
around_action
:handle_exceptions
private
def
handle_exceptions
begin
yield
rescue
NoPermissionError
redirect_to
'permission_error'
end
end
end
rescue_form
class
ApplicationController < ActionController::Base
rescue_from
'NoPermissionError'
do
|exception|
redirect_to
'permission_error'
end
end
exceptions_app
Caching
저레벨 캐싱 : 특정 값이나 쿼리의 결과만을 캐싱하고 싶은 경우에 사용. 블록을 인수로 넘기면 블록의 실행 결과가 주어진 키에 대해서 캐싱된다.
Rails.cache.fetch
메소드를 사용
위에서는 #{cache_key}를 사용하고 있다.
기타
validate
:rails 는 validates 키워드를 통해 데이터를 저장할때, 유효성 검사 메소드를 지원한다
validation trigger method
- create
- create!
- save
- save!
- update
- update!
skipping validations
- decrement!
- decrement_counter
- increment!
- increment_counter
- toggle!
- touch
- update_all
- update_attribute
- update_column
- update_columns
- update_counters
! : 메소드가 객체의 상태를 수정한다는 것을 의미
? : boolean을 리턴하는 true, false 를 묻는 메소드를 의미
respond_to
respond_to 는 rails 메소드. 해당 함수를 통하는 호출이 있었을 때, 어떻게 반응하도록 하겠는가를 정한다
|
위의 코드처럼 응답 요청에 대해서 whitelist화를 할 수 있다. (MIME html, js 요청에 대해서만 응답을 함)
아래처럼 block 처리를 이용할 수도 있다.
|
* ActiveRecord에서 scope
Active record로 DB에서 데이터를 조회할 때 조회 범위를 줄여준다거나 필터링 할때 주로 사용한다. (자주 사용되는 쿼리를 지정할 수 있다)
'기타' 카테고리의 다른 글
Ruby 기본 문법 (0) | 2017.09.12 |
---|