레일스 5.2 버전의 Active Storage 사용하기

레일스 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

이 때 다시 액티브스토리지를 사용하고자 할 경우에는,

  1. config/application.rb 파일을 열고 8번째 줄에 있는 # require "active_storage/engine" 코드라인의 코멘트 문자(#)를 삭제한다.
  2. 터미널에서 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
Running via Spring preloader in process 2553
      invoke  active_record
      create    db/migrate/20180128011730_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/models/post_test.rb
      create      test/fixtures/posts.yml
      invoke  resource_route
       route    resources :posts
      invoke  scaffold_controller
      create    app/controllers/posts_controller.rb
      invoke    erb
      create      app/views/posts
      create      app/views/posts/index.html.erb
      create      app/views/posts/edit.html.erb
      create      app/views/posts/show.html.erb
      create      app/views/posts/new.html.erb
      create      app/views/posts/_form.html.erb
      invoke    test_unit
      create      test/controllers/posts_controller_test.rb
      create      test/system/posts_test.rb
      invoke    helper
      create      app/helpers/posts_helper.rb
      invoke      test_unit
      invoke    jbuilder
      create      app/views/posts/index.json.jbuilder
      create      app/views/posts/show.json.jbuilder
      create      app/views/posts/_post.json.jbuilder
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/posts.coffee
      invoke    scss
      create      app/assets/stylesheets/posts.scss
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

이 때 생성된 마이그레이션 작업을 실행한다.

$ 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

homepage

위와 같은 페이지가 보이게 되면 지금까지 제대로 작업을 한 것이다.

이제 입력 폼에서 이미지를 업로드할 수 있도록 코드를 추가해 보자.

단수 이미지 추가하기

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)에 이미지 태그 추가하기


  <strong>Picture:</strong>

  <%= image_tag @post.picture, width: '50%' %>

복수 이미지 추가하기

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>

  <% @post.pictures.each do |picture| %>
    <%= image_tag picture, width: '10%' %>
  <% end %>

아마존 S3로 업로드하기

1) 아마존 S3에 버킷 생성하기

2) credentials 에 amazon_access_idsecret_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 버킷을 확인하면 다음과 같이 보일 것이다.

amazon_s3

References:

 

Posted in 미분류. Bookmark the permalink.