CarrierWave

画像のアップロード機能を実装する。

使い方

gemのインストール

gem 'carrierwave'
gem 'mini_magic'

bundle install

uploaderの作成

rails g uploader アップローダーの名前

例
rails g uploader image

これをすると以下が作成される
create  app/uploaders/image_uploader.rb

モデルへの関連付け

mount_uploader :image, ImageUploader
例
class Message < ApplicationRecord
  belongs_to :group
  belongs_to :user

  validates :content, presence: true, unless: :image?
  mount_uploader :image, ImageUploader
end

app/uploaders/image_uploader.rbのminiMagickのコメントアウトを外す

class ImageUploader < CarrierWave::Uploader::Base
  # Include RMagick or MiniMagick support:
  # include CarrierWave::RMagick
  include CarrierWave::MiniMagick

  process resize_to_fit: [800, 800]

ついでにresizeさせたい場合や処理がある場合にはコメントアウトを外した箇所の下の任意の場所に書く。

メソッド

.image

モデルに関連付けられた場合、Model.imageとしてもテーブルのimageカラムの値を取得しません。

Returns an instance of the uploader only if anything has been uploaded
と書かれている通り、インスタンスが返ります。

一見、imageカラムの文字列を参照するように思えますが、インスタンスが返ってきます。
なのでjson変換する際にjson.image hogehoge.imageとやったりすると
<img src=”[object” object]”=””>
とか出てオブジェクトなので扱えません状態になるので注意。
その場合は下のurlメソッドを併用します。

carrierwaveuploader/carrierwave
Classier solution for file uploads for Rails, Sinatra and other Ruby web frameworks - carrierwaveuploader/carrierwave

.image.urlメソッド

@message.image.urlとすることで/uploads以下のURLを取得できる。
.image_urlメソッドも定義されており、同じくURLを返す。

ローカルファイルをアップロード File.open()

仮テストする際にファイルアップロードをすると思います。
わざわざフォーム作ったりするのは面倒なのでどうやってするか調べました。
ファイルのpathを文字列で渡すのではダメで、file.openで渡しましょう。

class Test < ApplicationRecord
  def self.image
    pic = Picture.new
    pic.image = File.open("cat1.png")
    pic.save
  end
end

コメント