3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CarrierWave を使用した画像アップロード 〜 Rspec テスト 〜

Last updated at Posted at 2020-11-04

参考資料

carrierwaveuploader/carrierwave

画像(複数)アップロードにCarrierWaveを使ったRspec - Qiita

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

導入編

gem 'carrierwave', '~> 2.0'

bundle install した後、アップローダーの作成

be rails g uploader Images

app/uploaders/images_uploader.rb が作成される。

中身

class ImagesUploader < 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

Image テーブルに images カラム追加。(Image テーブル作成時に Post テーブルとの紐付け済み)

複数アップロードする場合、json 形式で保存するらしいので、指定しておく。

be rails g migration add_images_to_image images:json

migrate 中身

class AddImagesToImage < ActiveRecord::Migration[6.0]
  def change
    add_column :images, :images, :json
  end
end

rails db:migrate してカラムを追加

テストの実装

models/image.rb

class Image < ApplicationRecord
  belongs_to :post
  validates :images, presence: true

  mount_uploaders :images, ImagesUploader
end

spec/factories/images.rb

FactoryBot.define do
  factory :image do
    images { [ Rack::Test::UploadedFile.new(Rails.root.join('spec/fixtures/test.jpg'), 'spec/fixtures/test.jpg') ] }
    post
  end
end

spec ディレクトリ下に fixtures ディレクトリを作成。test.jpg を疑似的に作成し入れてます。

spec/models/images.rb

require "rails_helper"

RSpec.describe Image, type: :model do
  let(:pic_path) { Rails.root.join('spec/fixtures/test.jpg') }
  let(:pic) { Rack::Test::UploadedFile.new(pic_path) }

  context "画像が指定されれば" do
    it "画像がアップロードされる" do
      image = create(:image)
      expect(image).to be_valid
    end

    it "画像(複数)でもアップロードされる" do
      image = create(:image, images: [pic, pic])
      expect(image).to be_valid
    end
  end

  context "画像が指定されていないと" do
    it "エラーになる" do
      image = build(:image, images: nil)
      expect(image).to be_invalid
      expect(image.errors.messages[:images]).to eq ["can't be blank"]
    end
  end
end

追記(2020年12月11日)

アップロードのテスト中、アップロードした画像を削除する

画像アップロードのテスト中、毎度アップロードした画像が保存されてしまうので、テスト終了と同時にアップロードした画像を削除するようにした。

[CarrierWave]RSpec実行後の画像ファイルを削除する - Qiita

app/uploader/images_uploader

class ImagesUploader < CarrierWave::Uploader::Base
  # 中略
  def store_dir
    # テスト実行時はアップロードした画像を削除するように設定。
    if Rails.env.test?
      "uploads_#{Rails.env}/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    else
      "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
    end
  end

end

rails_helper

RSpec.configure do |config|
  # 中略
  # テスト実行時はアップロードした画像を削除するように設定
  config.after(:all) do
    if Rails.env.test?
      FileUtils.rm_rf(Dir["#{Rails.root}/public/uploads_#{Rails.env}/"])
    end
  end
end
3
2
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
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?