LoginSignup
2
4

More than 3 years have passed since last update.

【Rails】複数画像を保存したい時のcarrierwaveとMiniMagickの導入

Last updated at Posted at 2020-02-25

はじめに

syomaと申します。よろしくお願いいたします。
某プログラミングスクールの最終課題で某フリマアプリのクローンにて、商品出品における画像の複数投稿のための下準備でcarrierwaveとMiniMagickを導入しました。

環境

Rails 5.2.4.1
ruby 2.5.1

やりたいこと

  1. carrierwaveの導入
  2. MiniMagickの導入

↓最終形のイメージ
image.png

0.下準備

複数画像を投稿する場合は?対多(画像)になるので、Photoテーブルを作成し、カラム名はimageにしようと思います。※1枚のみであれば保存したいテーブルにimageカラムを追記するだけでOK!

保存先のテーブルを用意しましょう

以下のコマンドを実行してPhotoモデルを作成してください。

ターミナル
$ rails g model Photo

作成できたら、下記のファイルを記述を変更します。

db/migrate/****_create_photos.rb
class CreatePhotos < ActiveRecord::Migration[5.2]
  def change
    create_table :photos do |t|
      # ==========ここから追加する==========
      t.string :image, null: false
      t.references :good, foreign_key: true, null: false
      # ==========ここまで追加する==========
      # t.references :good, foreign_key: true, null: falseのgoodは
      # 紐付けたいテーブル名です。私の場合は商品に紐付けたかったのでGoodテーブルに紐づけております。
      # 人によってはテーブル名が異なるかと存じます。
      t.timestamps
    end
  end
end

では、マイグレーションファイルを実行してphotosテーブルを作成します。

ターミナル
$ rails db:migrate

アソシエーションの設定

モデルを作成したらアソシエーションの設定を行います。
アソシエーションとは、2つのモデル同士のつながりを指します。モデルとモデルの間には関連付けを行う必要があります。GoodモデルとPhotoモデルのアソシエーションを設定します。上記2つのモデルの関係性は以下のようになります。

  1. 一つの商品は複数の写真を持つことができる
  2. 写真Aに関して、写真Aに紐づく商品は一つしかない

つまり、GoodモデルとPhotoモデルは「1対多」の関係になります。
では、app/models/good.rbに以下のコードを追加してください。

good.rb
has_many :photos, dependent: :destroy

次にapp/models/photo.rbに以下のコードを追加してください。

photo.rb
belongs_to :good

これで、アソシエーションの設定は完了です。

1. carrierwaveの導入

carrierwaveはファイルを簡単かつ柔軟にアップロードする方法を提供するgem。

carrierwaveのGemをインストール

gemfile
gem "carrierwave"
ターミナル
$ bundle install

CarrierWaveのアップローダーを作成

ターミナル
$ rails g uploader Image

上記のコマンドを実行すると以下のファイルが作成されます。

ターミナル
create  app/uploaders/image_uploader.rb

image_uploader.rbでは、ファイルの保存方法(デフォルトはファイル)、保存パス、ファイルのサイズ、拡張子やファイル名の変換などが変更できます。

モデルのカラムにアップローダーを紐付け

Photoモデルのimageカラムと、先ほど作成したアップローダーImageUploaderと紐付けをします。(ImageUploaderはapp/uploaders/image_uploader.rbのクラスの名前です。)

app/models/photo.rbに以下のコードを追加してください。

photo.rb
class Photo < ApplicationRecord
  belongs_to :good , optional: true
  # ==========ここから追加する==========
  mount_uploader :image, ImageUploader
  # ==========ここまで追加する==========
end

2.MiniMagickの導入

MiniMagickは画像をリサイズできるgemです。Gemfileの最下部に以下のコードを追加します。

gemfile
gem "mini_magick"
ターミナル
$ bundle install

アップローダーの記述を修正

app/uploaders/image_uploader.rbを修正します。

ここで修正するのは以下の3点です。

  1. 4行目のすでに生成されているコードのコメントを外す
  2. 「version :middle」というサイズを指定するコードを追加 ※サイズを指定しない場合は不要
  3. extension_whitelistメソッドのコメントアウトを外す
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

  # ==========ここから追加する==========
  version :middle do
    process resize_to_fill: [188, 188]
  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
image_uploader.rb
  version :middle do
    process resize_to_fill: [188, 188]
  end

middleというバージョンが作成され、画像を188 x 188ピクセルにリサイズします。

最後に

実際の投稿は
【Ajax+Rails+Carrierwave】個別削除可能な画像複数(10枚まで)投稿
https://qiita.com/syoma/items/09a0d7bbadad35771a4d
にてご案内しております。もし、参考になったと思ったら「いいね」よろしくお願いいたします!

twitterもやっておりますので是非フォローよろしくお願いいたします。
https://twitter.com/syomabusiness
youtubeも始める予定です。

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4