0 【Rails5】carrierwaveとfogでAWS S3に画像を複数アップロードする方法 #rails #画像アップロード みんなに公開
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
画像アップローダーとは以下のようなものである。
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.rbserialize「シリアル化」とは複数の並列データを直列化して送信することであり、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.scss7. 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.rb8. 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.rb9. AWS S3へのアクセス環境変数設定をするため以下をターミナルで実行する
$ export AWS_ACCESS_KEY_ID= 自分のbucketのACCESS_KEY_IDを入れる
$ export AWS_SECRET_ACCESS_KEY= 自分のbucketのSECRET_ACCESS_KEYを入れる
※以上の実装はAWSS3にbucketを作成してからでないとできないので注意。
不明点、修正点ございましたらコメントよろしくお願いします。
serialize :images, JSON //複数の画像をアップロードをする場合は左の1文が必要である ←この一行に非常に助けていただきました!!悩んだ2日半が報われました!!ありがとうございました!!!