SlideShare ist ein Scribd-Unternehmen logo
1 von 39
Downloaden Sie, um offline zu lesen
BIWEEKLY LECTURE
THIS IS RAILS STYLE GUIDE 2
@pureugong
엑티브 레코드 쿼리
마이그레이션
뷰
국제화
메일러
시간
번들러
엑티브 레코드 쿼리
(ACTIVERECORD QUERIES)
SQL injection 공격에 취약할 수 있으므로, 쿼리에서 문자열
보간(string interpolation)을 사용하지 않는다.
# 나쁜 예 - 어떠한 매개변수든지 들어갈 수 있음
Client.where("orders_count = #{params[:orders]}")
# 좋은 예 - 적절한 매개변수만 들어갈 수 있음
Client.where('orders_count = ?', params[:orders])
쿼리에 하나 이상의 플레이스홀더를 사용할 때는 위치로 구분
되는 플레이스홀더 대신 이름을 붙여 사용한다.
# 괜찮은 예
Client.where(
'created_at >= ? AND created_at <= ?',
params[:start_date], params[:end_date]
)
# 좋은 예
Client.where(
'created_at >= :start_date AND created_at <= :end_date',
start_date: params[:start_date], end_date: params[:end_date]
)
id를 통해 하나의 값을 조회할 때는 where보다 find를 사용
한다.
# 나쁜 예
User.where(id: id).take
# 좋은 예
User.find(id)
특정 속성을 통해 하나의 값을 조회할 때는 where보단
find_by를 사용한다.
# 나쁜 예
# => ActiveRecord::Relation
User.where(first_name: 'Bruce', last_name: 'Wayne').first
# 좋은 예
User.find_by(first_name: 'Bruce', last_name: 'Wayne')
많은 레코드에 대해 어떤 작업을 해야한다면 find_each를
사용한다.
# 나쁜 예 - 모든 데이터를 한 번에 읽어온다.
# users 테이블이 수천개의 행을 가지고 있다면 매우 비효율적이다.
User.all.each do |user|
NewsMailer.weekly(user).deliver_now
end
# 좋은 예 - 배치(batch) 안에서 레코드를 가져온다.
User.find_each do |user|
NewsMailer.weekly(user).deliver_now
end
SQL을 직접 사용하기보다 'where.not'을 사용한다.
# 나쁜 예
User.where("id != ?", id)
# 좋은 예
User.where.not(id: id)
마이그레이션(MIGRATIONS)
schema.rb(또는 structure.sql) 파일을 VCS(버전
관리 시스템)에 포함시킨다.
빈 database를 초기화할 때는 rake db:migrate대신
rake db:schema:load를 사용한다.
기본 설정 값들은 애플리케이션에서 지정하기보다, 마이그레이
션 자체에 포함시킨다.
# 나쁜 예 - 애플리케이션에서 기본설정 값을 지정하는 예
def amount
self[:amount] or 0
end
테이블의 기본 설정 값을 레일즈 애플리케이션에서만 지정하는
것은 많은 레일즈 개발자들이 제안한 방법이지만, 이는 데이터
를 많은 어플리케이션 버그에 노출시키는 아주 불안정한 접근
방법이다. 그리고 대부분의 중요한 애플리케이션들은 하나의
데이터베이스를 다른 애플리케이션과 공유하기 때문에, 레일즈
애플리케이션을 통해 데이터 무결성을 보장하는 것은 불가능하
다는 사실을 고려해야한다.
외래키 제약을 사용한다. 레일즈 4.2부터 엑티브 레코드는 외
래키 제약을 기본적으로 지원한다.
(테이블이나 컬럼을 추가하는) 구조적인 마이그레이션을 작성
할 때는 up과 down메소드 대신 change메소드를 정의한
다.
# 예전 방식
class AddNameToPeople < ActiveRecord::Migration
def up
add_column :people, :name, :string
end
def down
remove_column :people, :name
end
end
# 새로운 방식
class AddNameToPeople < ActiveRecord::Migration
def change
add_column :people, :name, :string
end
end
마이그레이션에서 모델 클래스를 사용하지 않는다. 모델 클래
스들은 계속해서 변하기 때문에, 마이그레이션에서 사용한 모
델이 변화하게 되면 마이그레이션 작업이 정상적으로 수행되지
않을 수 있다.
뷰(VIEWS)
뷰에서 직접적으로 모델을 사용하지 않는다.
뷰에서는 절대 복잡한 포맷팅을 만들지 말고, 이러한 포맷팅은
뷰 헬퍼 메소드나 모델로 분리한다.
부분 템플릿(partial template)과 레이아웃을 이용하여 코드
중복을 줄인다.
국제화(INTERNATIONALIZATION)
뷰, 모델, 컨트롤러에서는 지역(locale) 관련 설정이나 문자열
을 바로 사용하지 않는다. 이러한 문자열들은
config/locales디렉터리 아래의 로케일 파일로 옮겨 관
리한다.
엑티브 레코드 모델의 레이블에 대한 번역이 필요할 때는
'activerecord' 아래에 작성한다.
en:
activerecord:
models:
user: Member
attributes:
user:
name: 'Full name'
이 때 User.model_name.human은 Member를 반환하고
User.human_attribute_name("name")은 "Full
name"을 반환한다. 이러한 속성들에 대한 번역은 뷰에서 레이블
로 사용된다.
뷰에서 사용되는 엑티브 레코드 속성들에 대한 번역은 분리한
다. models디렉터리에 모델을 위한 로케일 파일들을 저장하
고, 뷰에서 사용하는 텍스트는 views에 저장한다.
로케일(locale) 파일들을 적절한 위치에 저장하기 위해 디렉터
리를 추가로 만들었다면, 이 파일들을 읽어들일 수 있도록
application.rb파일에 설정해야 한다.
# config/application.rb
config.i18n.load_path += dir[rails.root.join('config', 'locales', '**'
날짜나 통화 형식과 같은 공유해서 사용할 수 있는 지역화 옵션
들은 locale바로 아래에 저장한다.
i18n의 짧은 형식의 메소드를 사용한다. i18n.translate
=> i18n.ti18n.localize=> i18n.l
뷰에서 사용되는 텍스트에 대해 게으른 참조(lazy lookup)를
사용한다. 게으른 참조란 번역 텍스트의 구조를 뷰 디렉터리 구
조와 같게 하여, 뷰에서 간단히 번역 텍스트를 참조하는 방법이
다. 예를 들어 다음과 같은 구조가 있다고 하자.
en:
users:
show:
title: 'user details page'
users.show.title의 값은
app/views/users/show.html.haml템플릿에서 다음
과 같이 사용될 수 있다.
= t '.title'
컨트롤러와 모델에서 :scope옵션을 사용하기보다, 점으로
분리된 키를 사용한다. 읽기도 쉽고 계층 구조를 파악하기도 쉽
다.
# 나쁜 예
I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages
# 좋은 예
I18n.t 'activerecord.errors.messages.record_invalid'
레일즈 I18n과 관련된 더 자세한 정보는
를 참고하라.
레일즈 가이드(Rails
Guides)
에셋 (ASSETS)
을 사용하라. 이는 애플리케이션 배포에 필요
한 에셋 파일들을 조직해줄 것이다.
커스텀 스타일시트, 자바스크립트, 이미지는 app/assets
디렉터리 아래에 저장한다.
애플리케이션에 포함되지 않는 직접 작성한 라이브러리들은
lib/assets에 저장한다.
에셋 파이프라인
나 와 같은 서드파티 라이브러리는
vendor/assets에 둔다.
가능하다면 젬으로 만들어진 에셋을 사용한다(예를 들어,
, , ,
).
jQuery bootstrap
jquery-rails jquery-ui-rails bootstrap-sass zurb-
foundation
메일러(MAILERS)
메일러의 이름은 'SomethingMailer' 형식을 따른다. 이러한
접미사가 없다면 메일러 클래스인지 바로 파악하기가 어렵고,
어떠한 뷰에 연결되어 있는지 찾아내기 어렵다.
HTML과 텍스트(plain text) 기반의 두 가지 템플릿을 각각 준
비한다.
참조
개발 환경에서 메일 전송에 실패하면 에러가 발생하도록 설정
한다.
기본 설정 값은 에러가 발생하지 않도록 설정되어 있다.
# config/environments/development.rb
config.action_mailer.raise_delivery_errors = true
개발 환경에서는 와 같은 로컬 SMTP 서버를 사
용한다.
Mailcatcher
# config/environments/development.rb
config.action_mailer.smtp_settings = {
address: 'localhost',
port: 1025,
# more settings
}
호스트의 이름을 기본 설정 값을 지정한다.
# config/environments/development.rb
config.action_mailer.default_url_options = { host: "#{local_ip}:3000"
# config/environments/production.rb
config.action_mailer.default_url_options = { host: 'your_site.com' }
# 메일러 클래스 안에서 설정
default_url_options[:host] = 'your_site.com'
이메일에 사이트의 링크를 넣고 싶다면 _path대신 _url메
소드를 사용한다. _url메소드는 호스트 이름을 같이 반환하
고, _path메소드는 그렇지 않다.
# 나쁜 예
# /coures
You can always find more info about this course
<%= link_to 'here', course_path(@course) %>
# 좋은 예
# http://localhost:3000/courses
You can always find more info about this course
<%= link_to 'here', course_url(@course) %>
보내는 사람(from)과 받는 사람(to)의 이메일 형식을 적절하게
지정한다. 다음 형식을 따른다.
# 메일러 클래스 안에서 설정한다
default from: 'Your Name <info@your_site.com>'
테스트 환경에서는 이메일 전송 메소드를 test로 설정한다.
# config/environments/test.rb
config.action_mailer.delivery_method = :test
개발 및 배포 환경에서는 이메일 전송 메소드가 smtp로 설정
되어 있어야 한다.
# config/environments/development.rb, config/environments/production.rb
config.action_mailer.delivery_method = :smtp
html 형식의 이메일을 전송할 때, 일부 클라이언트에서는 외부
스타일시트를 참조할 때 문제가 발생할 수 있기 때문에 css는
모두 인라인으로 작성되어야 한다. 하지만 인라인 스타일을 사
용하면 유지보수가 힘들고 코드 중복이 발생하게 된다. 스타일
과 html을 자동적으로 결합해주는 아래 두 가지 젬이 존재한
다. 와 .premailer-rails roadie
컨트롤러에서 요청에 대한 응답을 처리하는 도중에 이메일을
보내서는 안 된다. 이는 페이지 로딩을 지연시키고, 여러 메일
을 동시에 발송할 때 타임아웃이 될 수도 있다. 이메일 전송은
과 같은 백그라운드 작업을 지원하는 젬을 사용해 이루
어져야 한다.
sidekiq
시간(TIME)
application.rb에 타임존을 적절히 설정한다.
config.time_zone = 'Eastern European Time'
# 아래 옵션에는 :utc나 :local만을 지정할 수 있다. (기본 설정 값은 :utc)
config.active_record.default_timezone = :local
Time.parse를 사용하지 않는다.
# 나쁜 예
Time.parse('2015-03-02 19:05:37')
# => 이 메소드는 시스템 타임존에서 시간이 주어진 것으로 가정함
# 좋은 예
Time.zone.parse('2015-03-02 19:05:37')
# => Mon, 02 Mar 2015 19:05:37 EET +02:00
Time.now를 사용하지 않는다.
# 나쁜 예
Time.now # => 타임존 설정과 무관하게 시스템의 시간을 반환한다
# 좋은 예
Time.zone.now # => Fri, 12 Mar 2014 22:04:47 EET +02:00
Time.current # 위와 같지만 더 짧은 방법

Weitere ähnliche Inhalte

Was ist angesagt?

[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...
[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...
[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
.NET Webservice for MySQL
.NET Webservice for MySQL.NET Webservice for MySQL
.NET Webservice for MySQLI Goo Lee
 
Spring MVC
Spring MVCSpring MVC
Spring MVCymtech
 
[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기YoungSu Son
 
아키텍트가 바라보는 Spring framework
아키텍트가 바라보는 Spring framework아키텍트가 바라보는 Spring framework
아키텍트가 바라보는 Spring frameworkHaeil Yi
 
Angular js quick start
Angular js quick startAngular js quick start
Angular js quick start정기 김
 
E government framework
E government frameworkE government framework
E government frameworkHyungKuIm
 
#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
Spring mvc
Spring mvcSpring mvc
Spring mvcksain
 
04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)Hankyo
 
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처 스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처 Sungchul Park
 

Was ist angesagt? (11)

[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...
[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...
[국비지원교육/재직자/실업자환급교육/IT실무학원추천/스프링교육추천]#5.스프링프레임워크 & 마이바티스 (Spring Framework, M...
 
.NET Webservice for MySQL
.NET Webservice for MySQL.NET Webservice for MySQL
.NET Webservice for MySQL
 
Spring MVC
Spring MVCSpring MVC
Spring MVC
 
[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기[NEXT] Andorid에 MVC 패턴 적용하기
[NEXT] Andorid에 MVC 패턴 적용하기
 
아키텍트가 바라보는 Spring framework
아키텍트가 바라보는 Spring framework아키텍트가 바라보는 Spring framework
아키텍트가 바라보는 Spring framework
 
Angular js quick start
Angular js quick startAngular js quick start
Angular js quick start
 
E government framework
E government frameworkE government framework
E government framework
 
#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#33.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
Spring mvc
Spring mvcSpring mvc
Spring mvc
 
04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)04.실행환경 실습교재(화면처리)
04.실행환경 실습교재(화면처리)
 
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처 스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
스프링 코어 강의 3부 - 웹 애플리케이션 아키텍처
 

Ähnlich wie Rails style-guide-2

실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!Devgear
 
Web_06_Ruby On Rails (임시)
Web_06_Ruby On Rails (임시)Web_06_Ruby On Rails (임시)
Web_06_Ruby On Rails (임시)team air @ Dimigo
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 Yong Joon Moon
 
[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿AnselmKim
 
2014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #72014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #7Chris Ohk
 
Itcookbook Asp Chapter2
Itcookbook Asp Chapter2Itcookbook Asp Chapter2
Itcookbook Asp Chapter2xyzlee
 
신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판hyeonjae Cheon
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java유리 하
 
Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015sung yong jung
 
HeadFisrt Servlet&JSP Chapter 3
HeadFisrt Servlet&JSP Chapter 3HeadFisrt Servlet&JSP Chapter 3
HeadFisrt Servlet&JSP Chapter 3J B
 
Angular 2 rc5 조사
Angular 2 rc5 조사Angular 2 rc5 조사
Angular 2 rc5 조사Rjs Ryu
 
레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드Sukjoon Kim
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Javajigi Jaesung
 
ER/Studio를 활용한 데이터 표준화 시스템 구축방안
ER/Studio를 활용한 데이터 표준화 시스템 구축방안ER/Studio를 활용한 데이터 표준화 시스템 구축방안
ER/Studio를 활용한 데이터 표준화 시스템 구축방안Devgear
 
Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3plusperson
 
Daejeon IT Developer Conference iBATIS2
Daejeon IT Developer Conference iBATIS2Daejeon IT Developer Conference iBATIS2
Daejeon IT Developer Conference iBATIS2plusperson
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부quxn6
 
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴Devgear
 
04.실행환경 교육교재(화면처리)
04.실행환경 교육교재(화면처리)04.실행환경 교육교재(화면처리)
04.실행환경 교육교재(화면처리)Hankyo
 

Ähnlich wie Rails style-guide-2 (20)

C++ api design 품질
C++ api design 품질C++ api design 품질
C++ api design 품질
 
실전 DataSnap!
실전 DataSnap!실전 DataSnap!
실전 DataSnap!
 
Web_06_Ruby On Rails (임시)
Web_06_Ruby On Rails (임시)Web_06_Ruby On Rails (임시)
Web_06_Ruby On Rails (임시)
 
파이썬 플라스크 이해하기
파이썬 플라스크 이해하기 파이썬 플라스크 이해하기
파이썬 플라스크 이해하기
 
[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿[스프링 스터디 1일차] 템플릿
[스프링 스터디 1일차] 템플릿
 
2014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #72014-15 Intermediate C++ Study #7
2014-15 Intermediate C++ Study #7
 
Itcookbook Asp Chapter2
Itcookbook Asp Chapter2Itcookbook Asp Chapter2
Itcookbook Asp Chapter2
 
신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판신입 웹 개발자 포트폴리오 / 댓글 게시판
신입 웹 개발자 포트폴리오 / 댓글 게시판
 
[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java[HaU] 신입 기술 면접 준비 java
[HaU] 신입 기술 면접 준비 java
 
Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015Isomorphicspring Isomorphic - spring web seminar 2015
Isomorphicspring Isomorphic - spring web seminar 2015
 
HeadFisrt Servlet&JSP Chapter 3
HeadFisrt Servlet&JSP Chapter 3HeadFisrt Servlet&JSP Chapter 3
HeadFisrt Servlet&JSP Chapter 3
 
Angular 2 rc5 조사
Angular 2 rc5 조사Angular 2 rc5 조사
Angular 2 rc5 조사
 
레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드레일스를 이용한 애자일 웹 개발 가이드
레일스를 이용한 애자일 웹 개발 가이드
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
ER/Studio를 활용한 데이터 표준화 시스템 구축방안
ER/Studio를 활용한 데이터 표준화 시스템 구축방안ER/Studio를 활용한 데이터 표준화 시스템 구축방안
ER/Studio를 활용한 데이터 표준화 시스템 구축방안
 
Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3
 
Daejeon IT Developer Conference iBATIS2
Daejeon IT Developer Conference iBATIS2Daejeon IT Developer Conference iBATIS2
Daejeon IT Developer Conference iBATIS2
 
이펙티브 C++ 789 공부
이펙티브 C++ 789 공부이펙티브 C++ 789 공부
이펙티브 C++ 789 공부
 
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
보다 빠른 SQL튜닝과 분석을 위한 새로운 툴
 
04.실행환경 교육교재(화면처리)
04.실행환경 교육교재(화면처리)04.실행환경 교육교재(화면처리)
04.실행환경 교육교재(화면처리)
 

Rails style-guide-2

  • 1. BIWEEKLY LECTURE THIS IS RAILS STYLE GUIDE 2 @pureugong
  • 3. 엑티브 레코드 쿼리 (ACTIVERECORD QUERIES) SQL injection 공격에 취약할 수 있으므로, 쿼리에서 문자열 보간(string interpolation)을 사용하지 않는다. # 나쁜 예 - 어떠한 매개변수든지 들어갈 수 있음 Client.where("orders_count = #{params[:orders]}") # 좋은 예 - 적절한 매개변수만 들어갈 수 있음 Client.where('orders_count = ?', params[:orders])
  • 4. 쿼리에 하나 이상의 플레이스홀더를 사용할 때는 위치로 구분 되는 플레이스홀더 대신 이름을 붙여 사용한다. # 괜찮은 예 Client.where( 'created_at >= ? AND created_at <= ?', params[:start_date], params[:end_date] ) # 좋은 예 Client.where( 'created_at >= :start_date AND created_at <= :end_date', start_date: params[:start_date], end_date: params[:end_date] )
  • 5. id를 통해 하나의 값을 조회할 때는 where보다 find를 사용 한다. # 나쁜 예 User.where(id: id).take # 좋은 예 User.find(id)
  • 6. 특정 속성을 통해 하나의 값을 조회할 때는 where보단 find_by를 사용한다. # 나쁜 예 # => ActiveRecord::Relation User.where(first_name: 'Bruce', last_name: 'Wayne').first # 좋은 예 User.find_by(first_name: 'Bruce', last_name: 'Wayne')
  • 7. 많은 레코드에 대해 어떤 작업을 해야한다면 find_each를 사용한다. # 나쁜 예 - 모든 데이터를 한 번에 읽어온다. # users 테이블이 수천개의 행을 가지고 있다면 매우 비효율적이다. User.all.each do |user| NewsMailer.weekly(user).deliver_now end # 좋은 예 - 배치(batch) 안에서 레코드를 가져온다. User.find_each do |user| NewsMailer.weekly(user).deliver_now end
  • 8. SQL을 직접 사용하기보다 'where.not'을 사용한다. # 나쁜 예 User.where("id != ?", id) # 좋은 예 User.where.not(id: id)
  • 9. 마이그레이션(MIGRATIONS) schema.rb(또는 structure.sql) 파일을 VCS(버전 관리 시스템)에 포함시킨다. 빈 database를 초기화할 때는 rake db:migrate대신 rake db:schema:load를 사용한다.
  • 10. 기본 설정 값들은 애플리케이션에서 지정하기보다, 마이그레이 션 자체에 포함시킨다. # 나쁜 예 - 애플리케이션에서 기본설정 값을 지정하는 예 def amount self[:amount] or 0 end
  • 11. 테이블의 기본 설정 값을 레일즈 애플리케이션에서만 지정하는 것은 많은 레일즈 개발자들이 제안한 방법이지만, 이는 데이터 를 많은 어플리케이션 버그에 노출시키는 아주 불안정한 접근 방법이다. 그리고 대부분의 중요한 애플리케이션들은 하나의 데이터베이스를 다른 애플리케이션과 공유하기 때문에, 레일즈 애플리케이션을 통해 데이터 무결성을 보장하는 것은 불가능하 다는 사실을 고려해야한다.
  • 12. 외래키 제약을 사용한다. 레일즈 4.2부터 엑티브 레코드는 외 래키 제약을 기본적으로 지원한다. (테이블이나 컬럼을 추가하는) 구조적인 마이그레이션을 작성 할 때는 up과 down메소드 대신 change메소드를 정의한 다.
  • 13. # 예전 방식 class AddNameToPeople < ActiveRecord::Migration def up add_column :people, :name, :string end def down remove_column :people, :name end end
  • 14. # 새로운 방식 class AddNameToPeople < ActiveRecord::Migration def change add_column :people, :name, :string end end
  • 15. 마이그레이션에서 모델 클래스를 사용하지 않는다. 모델 클래 스들은 계속해서 변하기 때문에, 마이그레이션에서 사용한 모 델이 변화하게 되면 마이그레이션 작업이 정상적으로 수행되지 않을 수 있다.
  • 16. 뷰(VIEWS) 뷰에서 직접적으로 모델을 사용하지 않는다. 뷰에서는 절대 복잡한 포맷팅을 만들지 말고, 이러한 포맷팅은 뷰 헬퍼 메소드나 모델로 분리한다. 부분 템플릿(partial template)과 레이아웃을 이용하여 코드 중복을 줄인다.
  • 17. 국제화(INTERNATIONALIZATION) 뷰, 모델, 컨트롤러에서는 지역(locale) 관련 설정이나 문자열 을 바로 사용하지 않는다. 이러한 문자열들은 config/locales디렉터리 아래의 로케일 파일로 옮겨 관 리한다. 엑티브 레코드 모델의 레이블에 대한 번역이 필요할 때는 'activerecord' 아래에 작성한다.
  • 18. en: activerecord: models: user: Member attributes: user: name: 'Full name' 이 때 User.model_name.human은 Member를 반환하고 User.human_attribute_name("name")은 "Full name"을 반환한다. 이러한 속성들에 대한 번역은 뷰에서 레이블 로 사용된다.
  • 19. 뷰에서 사용되는 엑티브 레코드 속성들에 대한 번역은 분리한 다. models디렉터리에 모델을 위한 로케일 파일들을 저장하 고, 뷰에서 사용하는 텍스트는 views에 저장한다.
  • 20. 로케일(locale) 파일들을 적절한 위치에 저장하기 위해 디렉터 리를 추가로 만들었다면, 이 파일들을 읽어들일 수 있도록 application.rb파일에 설정해야 한다. # config/application.rb config.i18n.load_path += dir[rails.root.join('config', 'locales', '**'
  • 21. 날짜나 통화 형식과 같은 공유해서 사용할 수 있는 지역화 옵션 들은 locale바로 아래에 저장한다. i18n의 짧은 형식의 메소드를 사용한다. i18n.translate => i18n.ti18n.localize=> i18n.l
  • 22. 뷰에서 사용되는 텍스트에 대해 게으른 참조(lazy lookup)를 사용한다. 게으른 참조란 번역 텍스트의 구조를 뷰 디렉터리 구 조와 같게 하여, 뷰에서 간단히 번역 텍스트를 참조하는 방법이 다. 예를 들어 다음과 같은 구조가 있다고 하자. en: users: show: title: 'user details page'
  • 24. 컨트롤러와 모델에서 :scope옵션을 사용하기보다, 점으로 분리된 키를 사용한다. 읽기도 쉽고 계층 구조를 파악하기도 쉽 다. # 나쁜 예 I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages # 좋은 예 I18n.t 'activerecord.errors.messages.record_invalid' 레일즈 I18n과 관련된 더 자세한 정보는 를 참고하라. 레일즈 가이드(Rails Guides)
  • 25. 에셋 (ASSETS) 을 사용하라. 이는 애플리케이션 배포에 필요 한 에셋 파일들을 조직해줄 것이다. 커스텀 스타일시트, 자바스크립트, 이미지는 app/assets 디렉터리 아래에 저장한다. 애플리케이션에 포함되지 않는 직접 작성한 라이브러리들은 lib/assets에 저장한다. 에셋 파이프라인
  • 26. 나 와 같은 서드파티 라이브러리는 vendor/assets에 둔다. 가능하다면 젬으로 만들어진 에셋을 사용한다(예를 들어, , , , ). jQuery bootstrap jquery-rails jquery-ui-rails bootstrap-sass zurb- foundation
  • 27. 메일러(MAILERS) 메일러의 이름은 'SomethingMailer' 형식을 따른다. 이러한 접미사가 없다면 메일러 클래스인지 바로 파악하기가 어렵고, 어떠한 뷰에 연결되어 있는지 찾아내기 어렵다. HTML과 텍스트(plain text) 기반의 두 가지 템플릿을 각각 준 비한다. 참조
  • 28. 개발 환경에서 메일 전송에 실패하면 에러가 발생하도록 설정 한다. 기본 설정 값은 에러가 발생하지 않도록 설정되어 있다. # config/environments/development.rb config.action_mailer.raise_delivery_errors = true
  • 29. 개발 환경에서는 와 같은 로컬 SMTP 서버를 사 용한다. Mailcatcher # config/environments/development.rb config.action_mailer.smtp_settings = { address: 'localhost', port: 1025, # more settings }
  • 30. 호스트의 이름을 기본 설정 값을 지정한다. # config/environments/development.rb config.action_mailer.default_url_options = { host: "#{local_ip}:3000" # config/environments/production.rb config.action_mailer.default_url_options = { host: 'your_site.com' } # 메일러 클래스 안에서 설정 default_url_options[:host] = 'your_site.com'
  • 31. 이메일에 사이트의 링크를 넣고 싶다면 _path대신 _url메 소드를 사용한다. _url메소드는 호스트 이름을 같이 반환하 고, _path메소드는 그렇지 않다. # 나쁜 예 # /coures You can always find more info about this course <%= link_to 'here', course_path(@course) %> # 좋은 예 # http://localhost:3000/courses You can always find more info about this course <%= link_to 'here', course_url(@course) %>
  • 32. 보내는 사람(from)과 받는 사람(to)의 이메일 형식을 적절하게 지정한다. 다음 형식을 따른다. # 메일러 클래스 안에서 설정한다 default from: 'Your Name <info@your_site.com>'
  • 33. 테스트 환경에서는 이메일 전송 메소드를 test로 설정한다. # config/environments/test.rb config.action_mailer.delivery_method = :test
  • 34. 개발 및 배포 환경에서는 이메일 전송 메소드가 smtp로 설정 되어 있어야 한다. # config/environments/development.rb, config/environments/production.rb config.action_mailer.delivery_method = :smtp
  • 35. html 형식의 이메일을 전송할 때, 일부 클라이언트에서는 외부 스타일시트를 참조할 때 문제가 발생할 수 있기 때문에 css는 모두 인라인으로 작성되어야 한다. 하지만 인라인 스타일을 사 용하면 유지보수가 힘들고 코드 중복이 발생하게 된다. 스타일 과 html을 자동적으로 결합해주는 아래 두 가지 젬이 존재한 다. 와 .premailer-rails roadie
  • 36. 컨트롤러에서 요청에 대한 응답을 처리하는 도중에 이메일을 보내서는 안 된다. 이는 페이지 로딩을 지연시키고, 여러 메일 을 동시에 발송할 때 타임아웃이 될 수도 있다. 이메일 전송은 과 같은 백그라운드 작업을 지원하는 젬을 사용해 이루 어져야 한다. sidekiq
  • 37. 시간(TIME) application.rb에 타임존을 적절히 설정한다. config.time_zone = 'Eastern European Time' # 아래 옵션에는 :utc나 :local만을 지정할 수 있다. (기본 설정 값은 :utc) config.active_record.default_timezone = :local
  • 38. Time.parse를 사용하지 않는다. # 나쁜 예 Time.parse('2015-03-02 19:05:37') # => 이 메소드는 시스템 타임존에서 시간이 주어진 것으로 가정함 # 좋은 예 Time.zone.parse('2015-03-02 19:05:37') # => Mon, 02 Mar 2015 19:05:37 EET +02:00
  • 39. Time.now를 사용하지 않는다. # 나쁜 예 Time.now # => 타임존 설정과 무관하게 시스템의 시간을 반환한다 # 좋은 예 Time.zone.now # => Fri, 12 Mar 2014 22:04:47 EET +02:00 Time.current # 위와 같지만 더 짧은 방법