Tech Racho エンジニアの「?」を「!」に。
  • 開発

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本ほか


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。