LoginSignup
43

More than 5 years have passed since last update.

Rails、carrierwaveの使い方。インストール方法

Last updated at Posted at 2016-09-27

はじめに

CarrierWaveの備忘録。
Railsは5。

Brew

ImageMagickをあらかじめ入れておく。
画像をS3に置くだけなら要らないけど、たいていの場合は加工するはず。

brew install imagemagick

Gemfile

RailsからS3にアクセスするためのGemと画像加工用にRMgickを入れておく。

# 画像保存
gem 'carrierwave'
# For Carrierwave(S3用)
gem 'fog'
# 画像加工用
gem 'rmagick'

設定ファイル

S3の設定を記載しておく。

initializers/carrierwave.rb
# S3を使用しているかを判定するためのメソッド。(ローカル環境ではS3を使わないため)
def use_s3?
  ENV['S3_ACCESS_KEY'] && ENV['S3_SECRET_KEY'] && ENV['S3_REGION'] && ENV['S3_BUCKET']
end

## CarrierWaveの設定
CarrierWave.configure do |config|
  # S3の設定
  if use_s3?
    config.fog_credentials = {
        :provider               => 'AWS',
        :aws_access_key_id      => ENV['S3_ACCESS_KEY'],
        :aws_secret_access_key  => ENV['S3_SECRET_KEY'],
        :region                 => ENV['S3_REGION'],
        # :host                   => '必要なら設定する'
        # :endpoint               => '必要なら設定する'
    }

    # S3のバケットを指定。
    config.fog_directory     = ENV['S3_BUCKET']
    # 一般公開させて無いS3の場合は以下の設定を行う。
    config.fog_public     = false
    # 一般公開されていない場合は以下の設定をする事で60秒間有効なURLを発行してくれる。
    config.fog_authenticated_url_expiration = 60
    CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
  end

  # public配下にキャッシュができると参照されてしまうので、予め変えておく。
  config.cache_dir = "#{Rails.root}/tmp/uploads"
end

モデル

画像はString型で定義する。

migrate.rb
class Images < ActiveRecord::Migration[5.0]
  def change
    create_table :images do |t|
      # 管理したい画像
      t.string :image
      # etc...

      t.timestamps
    end
  end
end
model.rb
# 画像をアップロードする際のルール(別ファイルにしておけば汎用的に使える。)
class ImageUploader < CarrierWave::Uploader::Base
  # S3を使用するか?
  if use_s3?
    storage :fog
  else
    storage :file
  end

  # S3やローカルの保存先。(以下の書式をそのまま書いておけば大抵問題無い)
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  # 以下のようなことができる。

  # リサイズしたり画像形式を変更するのに必要
  include CarrierWave::RMagick

  # 画像を100x100にリサイズする。
  process :resize_to_fill => [100, 100]

  # 保存形式をJPGにする
  process :convert => 'jpg'

  # サムネイルを生成する設定
  # version :thumb do
  #   process :resize_to_fill => [40, 40, gravity = ::Magick::CenterGravity]
  # end

  # jpg,jpeg,gif,pngしか受け付けない
  def extension_white_list
    %w(jpg jpeg png)
  end

  # 拡張子が同じでないとPNGをJPGとかにコンバートできないので、ファイル名を変更
  def filename
    super.chomp(File.extname(super)) + '.jpg' if original_filename.present?
  end

  # 別のバケットにアクセスする場合は以下のようにする。
  # https://blog.hello-world.jp.net/ruby/1449/
  # def fog_directory
  #   config = YAML.load_file("#{Rails.root}/config/carrierwave.yml")[Rails.env]
  #   config['fog_another_directory']
  # end

end

# 画像用モデル
class Image < ApplicationRecord
  # ファイルアップロード処理
  mount_uploader :image, ImageUploader
end

View

特に大した事はせず。

= simple_form_for(@image) do |f|
  -#アップロードする画像(確認画面を作ることもできるけど、本記事では割愛)
  = f.input :image, as: :file
  -#アップロードした画像を表示
  = image_tag f.image
  -#カラム名にremoveをつけてデータを送ると画像を消せる。
  = f.input :remove_image, as: :boolean
  = f.submit "画像アップ"

Controller

StrongParamsなどいろいろ割愛。。。

def post_image
  Image.new(params[:image]).save
end

まとめ

今まで自分でこれらのことをしてたけど、CarrierWaveを使うととても楽だった。
ただし、openなどでデータを取得して画像を設定したい場合にはややイレギュラーなことをする必要があった。
また、DBにblobとして格納する場合はCarrierWaveは使えない。
なので、要件に合わせて頑張る必要がある。

おまけ

URLから画像を拾ってきて画像を保存する方法。
もっといい方法があったら知りたい。

open(path, :allow_redirections => :safe) do |file|
  # 一時的にテンポラリーファイルを作る必要があった。
  temp_img_file = Tempfile.new('ファイル名')
  temp_img_file.binmode
  temp_img_file << file.read
  temp_img_file.rewind
  # UploadedFileもしくはCarrierWave::Uploader::Base形式にする必要がある。
  uploaded_file = ActionDispatch::Http::UploadedFile.new(
    filename: 'ファイル名',
    type: file.content_type,
    tempfile: temp_img_file)
  image.image = uploaded_file
  image.save
end

画像が横になる場合

以下のコードを記載する。

ImageUploader
  process :fix_rotate

  # 画像の向きを調整する。
  def fix_rotate
    manipulate! do |img|
      img = img.auto_orient
      img = yield(img) if block_given?
      img
    end
  end

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
43