1
2

More than 1 year has passed since last update.

carrierwaveとcocoonを使った複数枚画像投稿

Last updated at Posted at 2022-07-11

執筆中

概要

carrierwaveとcocoonを使った複数枚画像投稿機能。
結論から言うと、本体とは別に画像テーブルを作成し、formをcocoonで複製しないと、ハッシュ化した複数投稿はできない。(と、思う。)
いろいろな記事があるが、画像の名前をハッシュ化していなかったりとピンとくる記事がなかったのでそれらを補ったものを投稿する。

開発環境

・Ruby: 3.1.2
・Rails: 7.0.2
・OS: macOS Monterey

準備

テーブル構成

本が1に対して、画像が多のテーブル構造。
carrierwaveの公式サイトでは複数画像の時は、json形式のカラムを作り(本記事だとbook)、そこに配列形式で格納する方法が紹介されているが、この方法で実装するとファイル名のハッシュ化で詰む。(後の、画像テーブルは別で用意するにて詳述する)

# images
lass CreateNoticeImages < ActiveRecord::Migration[7.0]
  def change
    create_table :images,  comment: '投稿画像' do |t|
      t.references :book,       comment: '本',  null: false, foreign_key: true
      t.text :content,            comment: 'コンテント'

      t.timestamps
    end
  end
end
# book
class CreateBooks < ActiveRecord::Migration[7.0]
  def change
    create_table :books,  comment: '本' do |t|
      t.string :title,      comment: 'タイトル',    null: false
      t.text :body,         comment: '本文'

      t.timestamps
    end
  end
end

gem追加

gem 'carrierwave'
gem 'cocoon'
gem 'mini_magick'

uploaderクラスの追加

rails g uploader image

CarrierWave編集

ApplicationUploaderクラス

# frozen_string_literal: true

class ApplicationUploader < CarrierWave::Uploader::Base
  storage Settings.use_gcs ? :fog : :file

  # see CarrierWave::Uploader::Configuration#add_config
  def self.fog_public
    true
  end

  def extension_allowlist
    %w[jpg jpeg gif png pdf]
  end

  def content_type_allowlist
    %w[image/jpeg image/gif image/png application/pdf]
  end

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # このメソッドで画像名をハッシュ化してる。ここ大事。
  def filename
    "#{secure_token}.#{file.extension}" if file
  end

  def fog_directory
    if fog_public
      super
    else
      Settings.fog_directory_private
    end
  end

  protected

    def secure_token
      var = :"@#{mounted_as}_secure_token"
      model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
    end
end

ImageUploaderクラス

# frozen_string_literal: true

class ImageUploader < ApplicationUploader
  include CarrierWave::MiniMagick

  # override allowlist in ApplicationUploader
  def extension_allowlist
    %w[jpg jpeg gif png]
  end

  def content_type_allowlist
    %w[image/jpeg image/gif image/png]
  end

 # ここでサムネイル画像のサイズ指定してる。
 # image_tagで使いたかったら、.thumb.url のように指定する。
  version :thumb do
    process resize_to_fit: [300, 200]
  end

  class << self
    def accept_mimetypes
      new.content_type_allowlist.join(',')
    end
  end
end

注意点

画像テーブルは別で用意する

参考記事[1]
参考記事[2]

1
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
1
2