こんにちは、onoです。
以前、CarrierWaveを使って画像をアップロードするフォームを作成しました。
CarrierWaveは多機能で使いやすいGemだと思いますが、コードが大きく複雑なため、一般的な使い方から外れた場合や問題が発生した場合に処理を追っていくのが大変です。
そこで、今回は実装がシンプルで必要な機能を選んで追加できるShrineを使ってみます。
Shrineはファイルをアタッチするためのツールです。
主に画像をアップロードする際に利用されるのではないかと思います。
ShrineはJanko Marohnić氏(リポジトリはこちら)が2015年9月から開発しています。
主な特徴としては下記の2つが挙げられます。
プロジェクトを作成後、Gemfileに下記のGemを追加します。
gem 'shrine'
画像をアップロードするディレクトリの指定と使用するプラグインを宣言します。
アプリケーション全体で共通の設定は、config/initializers/で行います。
require "shrine" require "shrine/storage/file_system" # アップロードするディレクトリの指定 Shrine.storages = { cache: Shrine::Storage::FileSystem.new("public", prefix: "uploads/cache"), # temporary store: Shrine::Storage::FileSystem.new("public", prefix: "uploads/store"), # permanent } # 使用するプラグインの宣言 Shrine.plugin :activerecord Shrine.plugin :cached_attachment_data # for forms
アップロードした画像を管理するテーブルを作成します。
アップロードした画像の情報を保存するカラムはtext型の「xxx_data」という名前にします(xxxはモデルの中でアップローダをアタッチする際に指定するシンボル名)
class CreatePhotos < ActiveRecord::Migration[5.0] def change create_table :photos do |t| t.string :name, limit: 16, null: false t.text :image_data, comment: '「アップローダに渡すシンボル名_data」とい名前にする' t.timestamps end end end
モデルにアタッチするアップローダを実装します。
特にディレクトリに指定はありませんが、app/uploaders/に追加していきます。
class ImageUploader < Shrine end
実装したアップローダをアタッチします。
class Photo < ApplicationRecord include ImageUploader[:image] validates :name, presence: true, length: { maximum: 16 } end
下記の通り、scaffoldで生成したコードの一部を修正します。
def photo_params # before params.require(:photo).permit(:name, :image_data) # after params.require(:photo).permit(:name, :image) end
画像をアップロードするフォームを実装します。
アップロードした画像のアドレスはxxx_urlで取得できます(xxxはモデルの中でアップローダをアタッチする際に指定するシンボル名)
<%= form_for(photo) do |f| %> <!--省略--> <div class="field"> <%= f.label :name %> <%= f.text_field :name %> </div> <div class="field"> <%= f.label :image_data %> <% if photo.cached_image_data.present? %> <!--バリデーションに失敗した場合、ここで画像を表示する--> <%= image_tag photo.image_url %> <% end %> <%= f.hidden_field :image, value: photo.cached_image_data %> <%= f.file_field :image %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
フォームから画像をアップロードして保存すると、下記のようなレコードがインサートされます。
mysql> select * from photos; +----+------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+ | id | image_data | created_at | updated_at | +----+------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+ | 4 | {"id":"01ebba4bae62c5fb1ecd136224f9d1dd.jpg","storage":"store","metadata":{"filename":"1182774.rsz.jpg","size":2989,"mime_type":"image/jpeg"}} | 2017-04-16 11:41:19 | 2017-04-16 11:41:19 | +----+------------------------------------------------------------------------------------------------------------------------------------------------+---------------------+---------------------+ 1 row in set (0.00 sec)
今後はプラグインを追加して、ファイル名の変更、リサイズ、サムネイルの作成などを行なっていきます。