Rails ダウンロードした画像をCarrierWaveで保存する

RailsにCarrierWaveを導入して、ダウンロードした画像を保存する方法です。

概要

保存のながれ

ネット上の画像 → CarrierWaveでダウンロードしてファイルとして保存します。

表示のながれ

CarrierWaveが提供してくれる画像へのURLを使って、ブラウザで表示します。

導入

GemfileCarrierWaveを追加して、bundle installします。

gem 'carrierwave', '>= 1.0.0.beta', '< 2.0'
$ bundle install

Uploaderクラスの作成

CarrierWaveではUploaderクラスを作ってそこにいろいろな設定を書きます。早速作ってみます。

CarrierWaveをインストールすると、Railsにてrails generate uploaderコマンドが使えるようになります。Avatarという名前で作ります。

$ rails generate uploader Avatar

すると次のファイルができます。

app/uploaders/avatar_uploader.rb

中をみると、色々と設定が書いてあります。今回はデフォルトのまま使います。

class AvatarUploader < CarrierWave::Uploader::Base
 # ストレージの種類
 storage :file

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

Vagrantを使っている場合は、実行時につぎのようなNameErrorが発生することがあるので、一旦Vagrantを立ち上げ直しておくとよいかもしれません。

uninitialized constant モデル名::AvatarUploader (NameError)

モデルにCarrierWaveを関連付ける

適当なモデルにstring型のカラムを追加して、CarrierWaveを関連付けます。

例として、avatarカラム付きのUserモデルを作ります。

rails g model User avatar:string

作成されたapp/models/user.rbを開き、次のようにmount_uploaderで関連付けます。

class User < ActiveRecord
  mount_uploader :avatar, AvatarUploader
end

以上で準備は完了です。

とりあえず使ってみる

リモートサーバーにある画像をURL指定で取得して保存しようと思います。

remote_avatar_urlメソッドが使えるようになっているので、ここに画像のURLを設定します。あとはsave!を実行すれば画像がダウンロードされて保存されます。

u = User.new
u.remote_avatar_url = "https://foo.bar/sample.jpg"
u.save!

画像はpublic/uploadsに保存されているので確認してみましょう。

つづいて表示してみる

ブラウザで画像を表示してみます。まず、urlメソッドで画像のURLを確認します。

puts u.avatar.url
=> /uploads/user/avatar/1/sample.jpg

とのことです。ブラウザで早速表示してみます。

http://ドメイン/uploads/user/avatar/1/sample.jpg

表示されたら成功です。