--- Title: '【Rails5】carrierwaveとfogでAWS S3に画像を複数アップロードする方法 #rails #画像アップロード' Keywords: - rails - 画像アップロード Author: michiru Web: 'https://mimemo.io/m/3A2wRoN6Evo1zM6' --- ![2019-11-09 (3)](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/8ad4286e-b466-4289-bc3c-e87c9b8f0d89.png) *** ### 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への画像をアップロードできるようにする。 ```:Gemfile=53 gem 'carrierwave' gem 'fog-aws' ``` ``` $ bundle install ``` ### 3. 画像アップロード用のクラスを作成すつために「rails g uploader アップローダー名」をターミナルで実装する ``` $ rails g uploader image ``` 画像アップローダーとは以下のようなものである。 ![07-17-2017-1500241058](https://mimemo.s3-ap-northeast-1.amazonaws.com/attachment/3deddc02-f39f-4c94-afcb-4d12fe38d10d.png) ### 4. アップローダーを実装したいクラス(ここではboardクラス)に以下のコードを記述する ```:/app/models/board.rb=1 class Board < ApplicationRecord mount_uploaders :images, ImgUploader serialize :images, JSON //複数の画像をアップロードをする場合は左の1文が必要である belongs_to :user end ``` serialize「シリアル化」とは複数の並列データを直列化して送信することであり、JSONとはJavaScript Object Notationの略でデータフォーマットの一種である。{}波括弧で括りその中にデータが入る形式であり以下のようなものになる。 ``` { "user": "太郎", "age": 20, "gender": "男" } ``` ### 5. ストロングパラメーターに「images」カラムを追加する * 複数の画像をアップロードする場合はデータをJSON形式で保存する必要があるため、ストロングパラメーターには{images: []}と書く。 ```:/controllers/boards_controller.rb=1 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 ``` * 一枚の画像だけをアップロードしたい場合、カラム名は「:image」となる。その場合はストロングパラメーターに以下のような実装をする。 ``` def board_params params.require(:board).permit(:image, :title,....... ``` ### 6. アップローダーを実装したいviewと、画像を表示したいviewを編集する ```:/app/views/boards/new.html.erb=20 <%= f.label :images, "画像:" %> <%= f.file_field :images, multiple: true, accept: "image/*" %> ``` 「multiple: true」とすることで複数の画像がアップロードできる。「accept: "image/*"」とすることで画像ファイルしかアップロードできないようにする。 ```:/app/views/boards/show.html.erb=5 画像: <% @board.images.each do |image| %> <%= image_tag image, class: "board-images" %> <% end %> ``` ```:/app/stylesheets/styles.scss=1 .board-images { display: inline-block; width: 200px; height: 200px; } ``` *** ### 7. image_uploader.rbにある「storage :fog」をコメントアウトする ```:/uploaders/image_uploader.rb=1 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 ``` ### 8. initializersのファイル直下にcarrierwave.rbを自分で作成し以下をコピペする config.fog_directory には自分のbucket名を入れる。 ```:/initializers/carrierwave.rb=1 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:]\.\-\+]/ ``` ### 9. AWS S3へのアクセス環境変数設定をするため以下をターミナルで実行する ``` $ export AWS_ACCESS_KEY_ID= 自分のbucketのACCESS_KEY_IDを入れる $ export AWS_SECRET_ACCESS_KEY= 自分のbucketのSECRET_ACCESS_KEYを入れる ``` ※以上の実装はAWSS3にbucketを作成してからでないとできないので注意。 *** 不明点、修正点ございましたらコメントよろしくお願いします。