0 【Rails5】carrierwaveとfogでAWS S3に画像を複数アップロードする方法 #rails #画像アップロード みんなに公開

2019-11-09 (3)


1. 画像アップロード用のカラムを作成するため「rails g migration add_images_column_to_テーブル名 images:string」をターミナルで実装する

$ rails g migration add_images_column_to_boards images:string  

※今回は複数の画像を一度にアップロードさせたいためカラム名は「images」とし、テーブル名は「boards」とする。

2. Gemfileに'carrierwave'と'fog-aws'を追加しbundle installを実行する

'carrierwave'を利用することで手軽に画像をアップロードすることができ、fogと連携することでクラウド上にあるAWS S3への画像をアップロードできるようにする。

gem 'carrierwave'
gem 'fog-aws'
53 54Gemfile
$ bundle install

3. 画像アップロード用のクラスを作成すつために「rails g uploader アップローダー名」をターミナルで実装する

$ rails g uploader image

画像アップローダーとは以下のようなものである。
07-17-2017-1500241058

4. アップローダーを実装したいクラス(ここではboardクラス)に以下のコードを記述する

class Board < ApplicationRecord
  mount_uploaders :images, ImgUploader
  serialize :images, JSON //複数の画像をアップロードをする場合は左の1文が必要である 
  belongs_to :user
end
1 2 3 4 5/app/models/board.rb

serialize「シリアル化」とは複数の並列データを直列化して送信することであり、JSONとはJavaScript Object Notationの略でデータフォーマットの一種である。{}波括弧で括りその中にデータが入る形式であり以下のようなものになる。

{
    "user": "太郎",
    "age": 20,
    "gender": "男"
}

5. ストロングパラメーターに「images」カラムを追加する

  • 複数の画像をアップロードする場合はデータをJSON形式で保存する必要があるため、ストロングパラメーターには{images: []}と書く。
class BoardsController < ApplicationController
before_action :authenticate_user!, :only => [:new, :create]
    
    def new
    @board = Board.new
    end

    def index
    @boards = Board.all
    end
    
    def create
      @board = Board.new(board_params)
      @board.user_id=current_user.id
      if @board.save
          flash[:notice] = "掲示板に新規投稿されました"
          redirect_to boards_path
      else 
          flash[:notice] = "掲示板に新規投稿できませんでした"
          render :new
      end
    end

    def show
    @board = Board.find(params[:id])
    @user = User.find(@board.user_id)
    end
   
 private 
    def board_params
      params.require(:board).permit({images: []}, :title, :book_name, :author, :isbn_num, :category, :condition, :available_period, :remarks, :user_id).merge(:user_id => current_user.id)
    end

end
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34/controllers/boards_controller.rb
  • 一枚の画像だけをアップロードしたい場合、カラム名は「:image」となる。その場合はストロングパラメーターに以下のような実装をする。
   def board_params
      params.require(:board).permit(:image, :title,.......

6. アップローダーを実装したいviewと、画像を表示したいviewを編集する

<%= f.label :images, "画像:" %>
<%= f.file_field :images, multiple: true, accept: "image/*" %>
20 21/app/views/boards/new.html.erb

「multiple: true」とすることで複数の画像がアップロードできる。「accept: "image/*"」とすることで画像ファイルしかアップロードできないようにする。

画像:
<% @board.images.each do |image| %>
 <%= image_tag image, class: "board-images" %>
<% end %>
5 6 7 8/app/views/boards/show.html.erb
.board-images {
  display: inline-block;
  width: 200px;
  height: 200px;
}
1 2 3 4 5/app/stylesheets/styles.scss

7. image_uploader.rbにある「storage :fog」をコメントアウトする

class ImgUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  # include CarrierWave::MiniMagick

  # Choose what kind of storage to use for this uploader:
  # storage :file
  storage :fog
 
  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_whitelist
    %w(jpg jpeg gif png)
  end

  # Override the filename of the uploaded files:
  # Avoid using model.id or version_name here, see uploader/store.rb for details.
  # def filename
  #   "something.jpg" if original_filename
  # end
end
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21/uploaders/image_uploader.rb

8. initializersのファイル直下にcarrierwave.rbを自分で作成し以下をコピペする

config.fog_directory には自分のbucket名を入れる。

require 'carrierwave/storage/abstract'
require 'carrierwave/storage/file'
require 'carrierwave/storage/fog'
 
CarrierWave.configure do |config|
#   if Rails.env.production?
    config.storage :fog
    config.fog_provider = 'fog/aws'
    config.fog_directory  = '_bucket' #自分のbucketの名前を入れる
    config.fog_credentials = {
      provider: 'AWS',
      aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
      aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY'],
      region: 'ap-northeast-1', #日本の場合はregionはこのように設定
      path_style: true
    }
#   else
#     config.storage :file
#     config.enable_processing = false if Rails.env.test?
#   end
end
 
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23/initializers/carrierwave.rb

9. AWS S3へのアクセス環境変数設定をするため以下をターミナルで実行する

$ export AWS_ACCESS_KEY_ID= 自分のbucketのACCESS_KEY_IDを入れる
$ export AWS_SECRET_ACCESS_KEY= 自分のbucketのSECRET_ACCESS_KEYを入れる

※以上の実装はAWSS3にbucketを作成してからでないとできないので注意。


不明点、修正点ございましたらコメントよろしくお願いします。

0

メモを他の人に見せる

このメモを見せたい人に、このURL(今開いているページのURLです)を教えてあげてください

コメント(1)

  • someone

  • someone

  • serialize :images, JSON //複数の画像をアップロードをする場合は左の1文が必要である ←この一行に非常に助けていただきました!!悩んだ2日半が報われました!!ありがとうございました!!!