SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

これだけは押さえておきたい! Rails開発で使えるgemパッケージ/ツール

Railsアプリケーションにファイルを簡単にアップロードするgem「CarrierWave」と「Refile」

これだけは押さえておきたい! Rails開発で使えるgemパッケージ/ツール 第9回

  • X ポスト
  • このエントリーをはてなブックマークに追加

Refileの導入

 ここからは、Refileを使った実装例を紹介します。なお、紹介済みの手順でCarrierWaveの実装を行った後に以下の手順を試す場合は、いったん適用したマイグレーションをロールバックしておく必要があります。

bin/rails db:rollback

インストール

 GemfileにRefileを追記します。

[リスト 11]Gemfile
…(中略)…
gem 'refile', github: 'refile/refile', require: 'refile/rails'
…(中略)…

 このように、Rails 5.2では、GitHub上の最新のmasterブランチを使わないとエラーが発生します。rackの依存関係の問題で、古いバージョン(0.3.0)のRefileが入ってしまうことが原因です。このあたりは初心者にとってつまずきやすいポイントですが、公式のREADMEにも執筆時点では記載がなかったので注意が必要です。

 以下のコマンドを実行しRefileをインストールします。

bin/bundle

 執筆時点では、0.6.2がインストールされますが、Gemfileにバージョン指定すると依存関係が解決できずエラーとなるので「github: 'refile/refile'」と明示的に指定する必要があります。

マイグレーション

 articlesテーブルにアップロードするファイル関連用のカラムを追加するマイグレーションファイルを追加します。

bin/rails g migration add_image_to_articles image_id:string image_filename:string image_size:string image_content_type:string

 追加したカラムのprefixである「image」はすべて共通の名称である点に注意が必要です。

 追加する各カラムの用途は以下の通りです。

カラムの用途
カラム名 用途 
image_id ファイル固有のキー
image_filename アップロード時のファイル名
image_size アップロード時のファイルサイズ
image_content_type アップロードされたファイルのContent-Type

 なお、少し気をつける必要がある点があります。執筆時点の公式READMEに従うと、ファイルサイズを保存するカラム名は「image_content_size」なのですが、これだと意図するように動いてくれません。実際にはcontentが不要で「image_size」とすると正常に動作します。

 生成されたマイグレーションファイルは以下の通りです。

[リスト 12]db/migrate/20181121071428_add_image_to_articles.rb
class AddImageToArticles < ActiveRecord::Migration[5.2]
  def change
    add_column :articles, :image_id, :string
    add_column :articles, :image_filename, :string
    add_column :articles, :image_size, :string
    add_column :articles, :image_content_type, :string
  end
end

 以下のコマンドを実行してマイグレーションを適用します。

 bin/rails db:migrate

モデルの修正

 CarrierWaveと違い、Refileではアップローダー用のクラスはありません。モデルにattachmentというDSLでファイルアップロード用の名称(ここではimage)をシンボルで指定するだけで済みます。

[リスト 13]app/models/article.rb
class Article < ApplicationRecord
  attachment :image
…(中略)…

ビューファイルの修正

 まず、フォームに画像パス用のフィールドを追加します。以下のように修正します。

[リスト 14]app/views/articles/_form.html.erb
…(中略)…
  <div class="field">
    <%= form.label :image %>
    <%= form.attachment_field :image %>
  </div>
…(中略)…

 attachment_fieldは、Refileが提供するヘルパーメソッドです。引数にモデルで指定したattachmentの引数と同じ値(ここでは:image)を指定します。

 次に、アップロードした画像ファイルを表示するため、以下のように追加します。

[リスト 15]app/views/articles/show.html.erb
…(中略)…
<p>
  <strong>Image:</strong>
  <% if @article.image %>
    <%= image_tag attachment_url(@article, :image) %>
  <% end %>
</p>
…(中略)…

 attachment_urlヘルパーメソッドはRefileが提供するメソッドで、第1引数にモデルのインスタンスを指定し、第2引数にモデルで指定したattachmentの引数(ここでは:image)を指定します。attachment_urlはファイルアップロードされていない場合、例外が発生するので、上記のように@article.imageの存在チェックを入れる必要があります。

コントローラーの修正

 CarrierWave同様、Strong Parameters用の修正を行います。

[リスト 16]
…(中略)…
    def article_params
      params.require(:article).permit(:title, :body, :image)
    end
…(中略)…

シークレットキーの追加

 最後に、Refile用のシークレットキーを設定ファイルに記述します。設定するシークレットキーは任意で構いません。

ruby -r securerandom -e 'p SecureRandom.hex(64)'

 を実行して得られた値をセットしておきましょう。production環境では環境変数にするなど配慮が必要です。

[リスト 17]config/initializers/refile.rb
Refile.secret_key = '[SecureRandom.hex(64)の実行結果]'

動作確認

 CarrierWave同様、rails sコマンドでpumaサーバーを起動し、任意の記事を編集して画像がアップロードできることが確認できます。

 なお、Refileではアップロード後のファイルは、tmp/uploads/store/ディレクトリ配下にimage_idに入っているファイル固有のキーと、一致するファイル名で保持されます。

まとめ

 ここまで、ファイルアップローダーの主なgemのうち、CarrierWave/Refileを紹介しました。

 次回は、Shrineを紹介するとともに、Rails5.2から導入されたActiveStorageについても紹介する予定です。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
これだけは押さえておきたい! Rails開発で使えるgemパッケージ/ツール連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 竹馬 力(チクバ ツトム)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11329 2019/01/24 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング