Rails 5.2を待たずに今すぐActiveStorageを使ってみた(翻訳)

概要

原著者の許諾を得て翻訳・公開いたします。

Rails 5.2を待たずに今すぐActiveStorageを使ってみた(翻訳)

DHHは今年ActiveStorageという新しいコンポーネントの導入をアナウンスしました. ActiveStorageは、写真などのアップロードをRailsで直接管理します。

以来、ActiveStorageをRailsに統合するため多くの改良が加えられ、ActiveStorageは事実上利用可能になっています。本記事では、ActiveStorageを使うためにRailsをアップデートする方法を調べてみました。

警告: bleeding edgeバージョンのRailsを使うため、見たこともないような問題が引き起こされる可能性があります。

Rails向けにActiveStorageをセットアップする

  • 5.1.14より前のRailsを使っている場合は、Gemfileを変更して5.1.14にアップデートします。
gem 'rails', '~> 5.1', '>= 5.1.4'
  • $ bundle update railsを実行します。
  • $ rails app:updateを実行してコードの差分をすべて解決します。
  • 5.1.14へのアップグレードで問題ないことを確認します。
  • bleeding edgeバージョンのRailsにアップデートします。

Gemfileを以下のように変更します。

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end
...
gem 'rails', github: 'rails/rails'
gem 'arel', git: 'https://github.com/rails/arel.git'
gem 'bootsnap', '~> 1.1', '>= 1.1.5', require: false
  • $ bundle update railsを実行します。
  • $ bundle exec rails -vでbleeding edgeバージョンRails 5.2.0.alphaの表示を確認します。
  • アプリケーションのconfigを更新し、$ bundle exec rails app:updateを実行します。
  • アプリ起動前に$ ./bin/rails --tasksrails active_storage:installが実行可能タスクに表示されることを確認します。
  • $ ./bin/rails active_storage:installを実行し、マイグレーションファイルを生成します。
  • $ ./bin/rails db:migrateを実行します。これでSQliteデータベースでActiveStorageがサポートされます。

ActiveStorageでシンプルな画像をアップロードしてみる

ここまではRailsアプリでActiveStorageをサポートするための準備でした。アプリでActiveSupportが使えるようになったので、ActiveStorageを使って画像のpostを作成できるようにする簡単な機能を作ってみましょう。

  • $ ./bin/rails g model postでPostモデルを作成します。
  • 次のマイグレーションファイルでPostのテーブルにtitlebodyの2つのカラムを追加します。
# db/migrate/20171114063756_create_posts.rb
class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.string :title
      t.text :body

     t.timestamps
    end
  end
end
  • $ ./bin/rails g controller postsでPostsリソースのコントローラを作成します。

  • Postsリソースへのルーティングをconfig/routes.rbに追加します。

Rails.application.routes.draw do
  resources :posts
end
  • 画像とpostの関連付けが必要です。
class Post < ApplicationRecord
  has_many_attached :images
end
  • indexshowcreateアクションのコードを追加します。
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  # postのフォームをここで表示する
  def index
    @post = Post.new
  end
  # ここでpostを作成する
  def create
    post = Post.create! params.require(:post).permit(:title, :body)
    post.images.attach(params[:post][:images])
    redirect_to post
  end
  # 写真付きのpostをここで表示する
  def show
    @post = Post.find(params[:id])
  end
end
  • 以下のコードを持つindexのビューをpostに追加します。アップロード用フォームはlocalhost:3000/postsに表示されます。
# app/views/posts/index.html.erb
<%= form_with model: @post, local: true do |form| %>
  <%= form.text_field :title, placeholder: "Title" %><br>
  <%= form.text_area :body %><br><br>
  <%= form.file_field :images, multiple: true %><br>
  <%= form.submit %>
<% end %>
  • postを表示するビューを追加します。
# app/views/posts/show.html.erb
<%= image_tag @post.images.first %>
  • 写真を1枚送信してみると、ビューに画像が表示されます。

この画像は、アプリのルートレベルのstorageというディレクトリにローカル保存されますが、このファイルをAWS S3やGoogle Cloud、Azureなどのクラウドファイルストレージシステムにプッシュするよう設定することもできます。

ご覧のとおり、ActiveStorageのおかげでRailsのActiveRecordコンポーネントにうまく統合されたシンプルなファイル管理システムを使えました。ActiveStorageが成熟すれば、ファイル管理で主要なユースケースをカバーできるようになるでしょう。Rails向けのファイル管理システムは他にもいろいろありますが、最初にActiveStorageを検討することをおすすめします。

ActiveStorageのドキュメントもご覧ください。

本記事の最終的なコードはGitHubリポジトリでご覧いただけます。

自身のプロジェクトでActiveStorageを使った経験を共有してくださった@jeffreyguentherに感謝いたします。

関連記事

Rails 5.2ベータがリリース!内容をざっくりチェックしました

週刊Railsウォッチ(20170721)ActiveStorageは5.2で正式導入、Onigmoの脆弱性が修正、この夏読みたい名作Ruby本ほか

Ruby on RailsによるWEBシステム開発、Android/iPhoneアプリ開発、電子書籍配信のことならお任せください この記事を書いた人と働こう! Ruby on Rails の開発なら実績豊富なBPS

この記事の著者

hachi8833

Twitter: @hachi8833、GitHub: @hachi8833

コボラー、ITコンサル、ローカライズ業界、Rails開発を経てTechRachoの編集・記事作成を担当。
これまでにRuby on Rails チュートリアル第2版の半分ほど、Railsガイドの初期翻訳ではほぼすべてを翻訳。その後も折に触れてそれぞれ一部を翻訳。
かと思うと、正規表現の粋を尽くした日本語エラーチェックサービス enno.jpを運営。
実は最近Go言語が好き。
仕事に関係ないすっとこブログ「あけてくれ」は2000年頃から多少の中断をはさんで継続、現在はnote.muに移転。

hachi8833の書いた記事

BPSアドベントカレンダー

週刊Railsウォッチ

インフラ

BigBinary記事より

ActiveSupport探訪シリーズ