레일스 5.2부터 도입된 액티브스토리(Active Storage)는 아마존 S3
, 구글 클라우드 스토리지
, 마이크로소프트 Azure 스토리지
와 같은 클라우드 스토리지 서비스로 파일을 업로드 후 액티브레코드 객체에 첨부(attach)할 수 있도록 해 준다. Carrierwave
또는 Paperclip
같은 기존의 젬과 비교해 볼 때 기능이 매우 제한되어 있으나 레일스 방식으로 손쉽게 파일 업로드 기능을 손쉽게 구현할 수 있다는 장점이 있다. 아마 향후에 기능 개선을 통해서 더욱 기능이 확장될 것으로 기대해 본다.
이 글에서는 처음 액티브스토리지는 접하는 레일스 초급자를 대상으로 그 사용법을 알아 볼 것이다.
우선 설명을 돕기 위해서 다음과 같이 샘플 애플리케이션(active_storage_sample)을 생성한다. (루비 2.5.0 / 레일스 5.2.0.beta2)
$ rails new active_storage_sample
터미널에 표시되는 실행 결과 중 마지막 두 줄을 눈여겨 볼 필요가 있다.
$ rails active_storage:install
Copied migration 20180127233601_create_active_storage_tables.active_storage.rb from active_storage
레일스 5.2 버전부터는 디폴트로 액티브스토리 기능이 추가된다. 원치 않을 경우 --skip-active-storage
옵션을 추가하여 애플리케이션을 생성하면 된다.
$ rails new active_storage_sample --skip-active-storage
이 때 다시 액티브스토리지를 사용하고자 할 경우에는,
- config/application.rb 파일을 열고 8번째 줄에 있는
# require "active_storage/engine"
코드라인의 코멘트 문자(#)를 삭제한다. - 터미널에서
rails active_storage:install
명령을 실행한다.
$ rails active_storage:install
Copied migration 20180128010516_create_active_storage_tables.active_storage.rb from active_storage
액티브스토리지를 사용하기 전에 마이그레이션 명령을 실행한다.
$ rake db:create && rake db:migrate
Post 모델 Scaffold 생성하기
title
, content
두 개의 속성을 가지는 posts
테이블을 생성하고 액티브레코드로 연결하기 위해서 다음과 같은 명령을 실행한다.
$ rails g scaffold Post title content:text
이 때 생성된 마이그레이션 작업을 실행한다.
$ rails db:migrate
== 20180128011730 CreatePosts: migrating ======================================
-- create\_table(:posts) -> 0.0008s
== 20180128011730 CreatePosts: migrated (0.0009s) =============================
그리고 config/routes.rb 파일을 열고 루트 라우트를 지정한다.
Rails.application.routes.draw do
root 'posts#index'
resources :posts
end
이 단계에서 로컬 레일스 서버를 실행하고 브라우저에서 지금까지의 작업을 확인한다. 터미널에서 다음과 같이 레일스 서버를 실행한 후,
$ rails server
브라우저의 주소창에서 다음과 같이 입력하여 접속한다.
http://localhost:3000
위와 같은 페이지가 보이게 되면 지금까지 제대로 작업을 한 것이다. 이제 입력 폼에서 이미지를 업로드할 수 있도록 코드를 추가해 보자.
단수 이미지 추가하기
1) Post 클래스에서 attach 매크로 지정
class Post < ActiveRecord
has_one_attached :picture
end
2) PostsController 클래스에서 Strong 파라메터 지정
def post_params
params.require(:post).permit(:title, :content, :picture)
end
3) 폼 파셜(_form.html.erb)에 추가하기
<div class="field">
<%= form.label :picture %>
<%= form.file_field :picture %>
</div>
4) 뷰 템플릿 파일(show.html.erb)에 이미지 태그 추가하기
<p>
<%= image_tag @post.picture %>
</p>
복수 이미지 추가하기
1) Post 클래스에서 attach 매크로 지정
class Post < ActiveRecord
has_many_attached :pictures
end
2) PostsController 클래스에서 Strong 파라메터 지정
def post_params
params.require(:post).permit(:title, :content, :pictures => [])
end
3) 폼 파셜(_form.html.erb)에 추가하기
<div class="field">
<%= form.label :pictures %>
<%= form.file_field :pictures, multiple: true %>
</div>
4) 뷰 템플릿 파일(show.html.erb)에 이미지 태그 추가하기
<strong>Picture:</strong><br>
<% @post.pictures.each do |picture| %>
<%= link_to image_tag(picture.variant(resize: "100x100^", extent: '100x100', gravity: 'center')), url_for(picture) %>
<% end %>
아마존 S3로 업로드하기
1) 아마존 S3에 버킷 생성하기
2) credentials 에 amazon_access_id와 secret_access_key 추가하기
$ rails credentials:edit
aws:
access_key_id: xxxxxxxxxxxx
secret_access_key: xxxxxxxxxxxxxxxxxx
수정한 후 저장하면 자동으로 config/credentials.yml.enc
파일이 업데이트 된다.
3) 스토리지 환경변수 지정하기
config/storage.yml
파일을 열고 코멘트 처리되어 있는 부분을 아래와 같이 변경한다.
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: ap-northeast-2
bucket: [bucket-name]
4) 액티브스토리지 서비스를 로컬에서 아마존으로 변경
config/environments/development.rb
파일을 열고 아래와 같이 변경한다.
···
config.active_storage.service = :amazon
···
이제 로컬 서버를 재시동 한 후 파일 업로드를 시도한 후 아마존 S3 버킷을 확인하면 다음과 같이 보일 것이다.
References:
정리된 내용 덕에 좋은 정보 얻고 갑니다