@fukutechの技術ブログ

概要

要点

(1) Gemの追加

 - carrierwave gem  
 - mini_magick gem  
 - fog gems (本番環境用なので、group :production do ~ endの中に記述する)  

(2) CarrierWaveによる、Railsのジェネレーターで画像アップローダー生成

 $ rails g uploader Picture  

(3) マイグレーションファイルの生成

$ rails g migration add_picture_to_books picture:string  
$ rails db:migrate  

(4) 対象モデルにmount_uploaderメソッドを定義

 mount_uploader :picture, PictureUploader  

CarrierWaveに画像と関連付けたモデルを伝えるためには、mount_uploaderというメソッドを使います。このメソッドは、引数に属性名のシンボルと生成されたアップローダーのクラス名を取ります。

(5) Railsサーバーの再起動

  • 再起動しないとエラーが解消されないので注意。

(6) フォームにfile_filedタグを追加

<%= f.file_field :picture %>  

(7) createアクションに関連するprivateメソッド中のstrong parameterに画像情報を追加

params.require(:micropost).permit(:content, :picture)  

(8) 対象ビューに画像の表示用のコードを記述

<%= image_tag micropost.picture.url if micropost.picture? %>  

(9) テスト記述

  • テスト中での画像のアップロードは fixture_file_upload(file, type) を用いる

    picture = fixture_file_upload('test/fixtures/rails.png', 'image/png')  

(10) バリデーション設定

  • 画像サイズ
  • フォーマット

    (app/uploaders/picture_uploader.rb)  
    
    class PictureUploader < CarrierWave::Uploader::Base  
    storage :file  
    
    # アップロードファイルの保存先ディレクトリは上書き可能  
    # 下記はデフォルトの保存先    
    def store_dir  
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"  
    end  
    
    # アップロード可能な拡張子のリスト(コメントアウトされているので有効化)  
    def extension_whitelist  
      %w(jpg jpeg gif png)  
    end  
    end  
    
    app/models/micropost.rb  
    
    class Micropost < ApplicationRecord  
    ・  
    ・  
    ・  
    validate  :picture_size  
    
    private  
    
      # アップロードされた画像のサイズをバリデーションする  
      def picture_size  
        if picture.size > 5.megabytes  
          errors.add(:picture, "should be less than 5MB")  
        end  
      end  
    end  

(10) 定義した画像のバリデーションをビューに組み込むために、クライアント側に2つの処理を追加

  • file_fieldタグacceptパラメータを付与

    <%= f.file_field :picture, accept: 'image/jpeg,image/gif,image/png' %>   
  • JavaScript実装で大きすぎるファイルサイズに対して警告

    (例、フォーム送信をしているビューファイルに下記のようなコードを記述)  
    ・  
    ・  
    ・  
    $('#micropost_picture').bind('change', function() {  
    var size_in_megabytes = this.files[0].size/1024/1024;  
    if (size_in_megabytes > 5) {  
     alert('Maximum file size is 5MB. Please choose a smaller file.');  
    }  
    });  
    ・  
    ・  
    ・  

(11) 画像のリサイズ

  • ImageMagickのインストール

    $ brew install imagemagick  
  • ImageMagickがインストールされたか確認

    $ convert --version  
  • 画像アップローダーの編集

    (app/uploaders/picture_uploader.rb)  
    
    class PictureUploader < CarrierWave::Uploader::Base  
    include CarrierWave::MiniMagick  
    process resize_to_limit: [400, 400]  
    ・  
    ・  
    ・  
  • テスト環境ではリサイズしないように設定(これをしないとエラーが出続ける)

    (config/initializers/skip_image_resizing.rb)  
    
    if Rails.env.test?  
    CarrierWave.configure do |config|  
      config.enable_processing = false  
    end  
    end  

(12) 本番環境での画像アップロードを調整

(app/uploaders/picture_uploader.rb)  

 class PictureUploader < CarrierWave::Uploader::Base  
   include CarrierWave::MiniMagick  
   process resize_to_limit: [400, 400]  

   if Rails.env.production?  
     storage :fog  
   else  
     storage :file  
   end  
   ・  
   ・  
   ・  

(13) 本番環境でクラウドストレージに保存するための設定

  • AWSのS3を用いる場合を想定
  • セットアップを行う
  • CarrierWaveの設定ファイルの修正

    (config/initializers/carrier_wave.rb)  
    
    if Rails.env.production?  
    CarrierWave.configure do |config|  
      config.fog_credentials = {  
        # Amazon S3用の設定  
        :provider              => 'AWS',  
        :region                => ENV['S3_REGION'],     # 例: 'ap-northeast-1'  
        :aws_access_key_id     => ENV['S3_ACCESS_KEY'],  
        :aws_secret_access_key => ENV['S3_SECRET_KEY']  
      }  
      config.fog_directory     =  ENV['S3_BUCKET']  
    end  
    end  
  • 上記設定において、Herokuの環境変数 ENV を使って、機密情報が漏洩しないようにすること
  • $ heroku config:setコマンドを使って、次のようにHeroku上の環境変数を設定
    $ heroku config:set S3_ACCESS_KEY="ココに先ほどメモしたAccessキーを入力"  
    $ heroku config:set S3_SECRET_KEY="同様に、Secretキーを入力"  
    $ heroku config:set S3_BUCKET="Bucketの名前を入力"  
    $ heroku config:set S3_REGION="Regionの名前を入力"  

(14) .gitignoreファイルにアップロード用ディレクトリを追加

(.gitignore)  

  # アップロードされたテスト画像を無視する  
  /public/uploads  

このログへのコメント

コメントはありません