#author("2022-06-30T07:24:14+00:00","default:src128","src128")
#author("2022-10-22T05:21:34+00:00","default:src128","src128")
&tag(CarrierWave);
*目次 [#m00f5025]
#contents
*関連ページ [#xb0b63f5]
*参考情報 [#tc3a51e3]
-[[carrierwaveuploader/carrierwave:https://github.com/carrierwaveuploader/carrierwave]] …公式サイト
-[[Rails 超お手軽な画像アップローダー CarrierWave の使い方 | Workabroad.jp:http://www.workabroad.jp/tech/1118]]

*デモプロジェクトの作成2022年版 [#i2ddbd9e]

**Gemfile [#r4f528c7]
-以下を追加し、bundle updateを実行。記事執筆時carrierwave 2.2.2となった。
#pre{{
gem 'carrierwave'
gem 'rmagick'
}}

**準備 [#p5aff167]
-アップローダーの生成
#pre{{
$ bundle exec rails g uploader image
}}

-マイグレーションファイル
#pre{{
$ bundle exec rails g migration add_image_to_books image:string
#=> db/migrate/xxxxx_add_image_to_users.rbが生成される。
}}

-マイグレーション実行。Booksテーブルにimageカラムが追加される。imageカラムにはファイル名が保存される。
#pre{{
$ bundle exec rake db:migrate
}}

-Bookモデルにアップローダーをマウント。
#pre{{
class Book < ApplicationRecord
  validates :title, :presence => true
  # 下記を追加
  mount_uploader :image, ImageUploader
end
}}

-controllerを変更。
#pre{{
    def book_params
      params.require(:book).permit(:title, :author, :summary, :image)
    end
}}

** Uploaderの修正 [#u0b82161]
-app/uploaders/image_uploader.rbを編集し、画像サイズや、ファイルの保管場所などの設定を行う。

** Viewの編集 [#zc0b238d]
-編集画面。_form.html.erb
#pre{{
<%= form_with(model: book) do |form| %>
(中略)
  <div class="field">
    <%= form.label :image %>
    <%= form.file_field :image %>
  </div>
(中略)
<% end %>
}}

-表示画面。show.html.erb。@book.image.urlでアクセス。
#pre{{
    <% if @book.image? %>
        <%= image_tag @book.image.url %>
    <% else %>
        画像がありません
    <% end %>
}}
-縮小画像を使用したい場合uploaderをカスタムする必要あり。


*デモプロジェクトの作成 [#i2ddbd9e]

**Gemfile [#r4f528c7]
-以下を追加し、bundle updateを実行
#pre{{
gem 'carrierwave'
gem 'rmagick'
}}

**準備 [#p5aff167]
-アップローダーの生成
#pre{{
$ bundle exec rails g uploader image
}}

-マイグレーションファイル
#pre{{
$ bundle exec rails g migration add_image_to_books image:string
#=> db/migrate/xxxxx_add_image_to_users.rbが生成される。
}}

-マイグレーション実行。Booksテーブルにimageカラムが追加される。imageカラムにはファイル名が保存される。
#pre{{
$ bundle exec rake db:migrate
}}

-Bookモデルにアップローダーをマウント。
#pre{{
class Book < ActiveRecord::Base
  validates :title, :presence => true
  # 下記を追加
  mount_uploader :image, ImageUploader
end
}}

-controllerを変更。
#pre{{
    def book_params
      params.require(:book).permit(:title, :author, :summary, :image)
    end
}}

** Uploaderの修正 [#u0b82161]
-app/uploaders/image_uploader.rbを編集し、画像サイズや、ファイルの保管場所などの設定を行う。

** Viewの編集 [#zc0b238d]
-編集画面。
#pre{{
<%= form_for(@book) do |f| %>
      (...省略...)
      <%= f.label :image %>
      <%= f.file_field :image %>
      (...省略...)
<% end %>

}}

-表示画面。@book.image.<アップローダーで付けた縮小画像の名前>.urlでアクセス。
#pre{{
    <% if @book.image? %>
        <%= image_tag @book.image.s.url %>
    <% else %>
        画像がありません
    <% end %>
}}

*Tips [#lbb680c6]
**ちょっとだけ異なるUploaderを作りたい。 [#pa89bc25]
-例えばimage1とimage2でベースとなるファイル名だけ変えたい場合。CarrierWave::Uploader::Baseを継承したベースクラスを作りそこからさらに継承するのはできない(仕様上うまく動かないらしい)。
-Uploaderからカラム名などにアクセスできるのでそれを使うのが簡単かも。例えばカラム名をそのままファイル名に使いたい場合、mount_asが使える。
--book.rb
#pre{{
class Book < ActiveRecord::Base
  validates :title, :presence => true
  # 下記を追加
  mount_uploader :image, ImageUploader
  mount_uploader :image2, ImageUploader
end
}}
--image_uploader.rb。マウントされたカラムによってファイル名が変わる。
#pre{{
  def filename
#    "image1.jpg" or "image2.jpg"
    "#{mounted_as}.jpg"
  end
}}

**縮小すると画質が劣化する [#k3c45421]
-[[How to: Specify the image quality &#183; carrierwaveuploader/carrierwave Wiki:https://github.com/carrierwaveuploader/carrierwave/wiki/How-to:-Specify-the-image-quality]]にある方法でqualityは指定できる(があまり影響なし?)。それだけでなくunsharp_maskも指定したほうがいいかも。config/initializers/carrierwave.rbを作成。
#pre{{
module CarrierWave
  module RMagick

    def quality(percentage)
      manipulate! do |img|
        img.write(current_path){ self.quality = percentage } unless img.quality == percentage
        img = yield(img) if block_given?
        img
      end
    end

    # reduce image noise and reduce detail levels
    #
    #   process :blur => [0, 8]
    #
    def blur(radius, sigma)
      manipulate! do |img|
        img = img.blur_image(radius, sigma)
        img = yield(img) if block_given?
        img
      end
    end

    def unsharp_mask(radius, sigma, amount, threshold)
      manipulate! do |img|
        img = img.unsharp_mask(radius, sigma, amount, threshold)
        img = yield(img) if block_given?
        img
      end
    end

  end
end
}}
-ImageUploaderで指定する。ImageMagicの縮小オプションだと「convert -quality 90 -unsharp 2x1.4+0.5+0 -resize 560x560」に相当?
#pre{{
class ImageUploader < CarrierWave::Uploader::Base

  version :m do
    process :resize_to_limit => [560, 560]
    process :quality => 90
    process :unsharp_mask => [2, 1.4, 0.5, 0]
  end

end
}}

*トラブルシューティング [#pd356661]

**undefined method `quality' [#q05cebb4]
-qualityは標準のメソッドではなくconfig/initializers/carrierwave.rbに追加した独自メソッドである。
-2022/10/22(土)rmagick5で上記エラーが発生するように。とりあえず4.3にしたらエラー解消。

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS