Help us understand the problem. What is going on with this article?

【Rails】Carrierwaveを用いて画像を複数アップロードする方法

目標

ezgif.com-video-to-gif.gif

開発環境

・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

前提

下記実装済み。

Slim導入
ログイン機能実装
投稿機能実装

実装

1.Gemを導入

Gemfile
gem 'carrierwave'
gem 'mini_magick'

gem 'mini_magick'
➡︎ 画像のサイズをアップロード時に変更出来る様にする。

ターミナル
$ bundle

2.画像設定ファイルを作成

ターミナル
$ rails g uploader image

app/uploaders/image_uploader.rbに下記ファイルが作成されます。
設定方法は後ほど説明します。

uploaders/image_uploader.rb
class ImageUploader < 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

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # Provide a default URL as a default if there hasn't been a file uploaded:
  # def default_url(*args)
  #   # For Rails 3.1+ asset pipeline compatibility:
  #   # ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
  #
  #   "/images/fallback/" + [version_name, "default.png"].compact.join('_')
  # end

  # Process files as they are uploaded:
  # process scale: [200, 300]
  #
  # def scale(width, height)
  #   # do something
  # end

  # Create different versions of your uploaded files:
  # version :thumb do
  #   process resize_to_fit: [50, 50]
  # end

  # 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

3.カラムを追加

ターミナル
$ rails g migration AddImagesToBooks images:json
ターミナル
$ rails db:migrate
schema.rb
create_table "books", force: :cascade do |t|
  t.integer "user_id"
  t.string "title"
  t.text "body"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
  t.json "images"
end

4.モデルを編集

book.rb
# 追記
mount_uploaders :images, ImageUploader

5.コントローラーを編集

ストロングパラメーターに{ images[] }を追加し、カラムに配列で保存出来る様にする。

books_controller.rb
def book_params
  params.require(:book).permit(:title, :body, { images: [] })
end

6.ビューを編集

①画像投稿フォームを作成

multiple: trueを付与する事で画像を複数選択出来る様になる。

books/~.html.slim
= f.file_field :images, multiple: true
br

②画像を表示させる

imagesカラムを「5.コントローラーを編集」で配列にして、そこに画像が複数入るので、eachで回して取り出す。

.to_sを付与しないと画像が表示されない。

books/~html.slim
td
  - book.images.each do |image|
    = image_tag image.to_s

設定について

1.画像サイズの設定

include CarrierWave::MiniMagickを追記し、その下にサイズ設定を記述する。

process resize_to_fill(おすすめ)
縦横比を維持せずに、元画像から指定サイズ(100, 100)で指定位置('Center')から切り抜きを行う。

uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  process resize_to_fill: [100, 100, 'Center']
end

スクリーンショット 2020-06-06 9.59.35.png

process resize_to_fit
縦横比を維持し、 widthを最大300px、heightを最大200pxでリサイズ出来る。

uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  process resize_to_fit: [100, 100]
end

スクリーンショット 2020-06-06 10.00.23.png

2.拡張子の制限

image_uploader.rbの38~40行目をアンコメントする。
デフォルトではjpg、jpeg、gif、png以外の拡張子だった場合はアップロード出来ない。

uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  def extension_whitelist
    %w(jpg jpeg gif png)
  end
end
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away