Help us understand the problem. What is going on with this article?

Cloudinary + Carrierwave + Heroku + Railsでの画像を手軽に利用する方法

More than 5 years have passed since last update.

現在、Herokuで利用されているCedarスタックは、画像の保存はできるものの、Herokuを再起動したり、Pushすると保存していた画像が消えてしまいます。
そのため、Herokuのアプリケーション内で画像を保存するためには外部のストレージが必須です。
AWSのS3などもありますが、Herokuと親和性の高いCloudinaryがすごく便利です。
備忘録としてまとめましたので、ご活用ください。

Heokuへの追加とCloudinaryでの確認

Herokuへの追加

まずは、Herokuにアドオンを追加します

console
$heroku addons:add cloudinary:starter

または HerokuのdashboardからAdd-onsからCloudinaryを追加して下さい。
※最初はStarterで良いと思います。

Cloudinaryでの確認

  1. HerokuのAppからアドオンを追加したアプリを選択しでCloudinaryをクリックしすると、Herokuと連携したCloudinaryのWebサイトが開きます。

  2. はじめてCloudinaryのサイトを開くと、あなたはどの言語/フレームワークを利用しますか?のような質問がでてきますので、ここではRuby on Railsを選択します。

  3. RoRに関するドキュメントが表示されます。
    Configurationの項にdownload your customized cloudinary.yml configuration fileというリンクから、cloudinary.ymlをダウンロードしておいてください。

CloudinaryとCarrierwaveの実装

もろもろ追加

gemを追加します

console
$gem install carrierwave
$gem install cloudinary

Gemfileへ追加。ついでにHerokuの環境も追加。

gemfile
source 'https://rubygems.org'

gem 'rails', '3.2.8'

gem 'carrierwave'
gem 'cloudinary'

gem 'heroku'

group :test, :development do
    gem 'sqlite3'
end

group :production do
    gem 'pg'
    gem 'thin'
end

group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

bundle installを実行

console
$bundle install

デモアプリ作成

ユーザー名と顔写真を表示するアプリです。

console
$rails new coudinary_demo

$cd cloudinary_demo

$rm -f public/index.html

$rails g scaffold User name:string avatar:string remove_avatar:boolean avatar_cache:string

$rake db:migrate

avatar は保存する画像を文字列にして保存。
remove_avatar は画像の削除に利用。
avatar_cache は画像のアップロードが失敗時、表示するために利用。

config/routes.rb
CloudinaryDemo::Application.routes.draw do
  resources :users

  root :to => 'users#index'  
end

ブラウザでhttp://localhost:3000にアクセスするとアプリのトップ画面が表示されます。

avatar_uploader.rbを作成

次に画像のアップローダーを作ります。

console
rails g uploader Avatar

avatar_uploader.rbを編集

コメントで色々と入力されていますが、
ざっくり置き換えて下さい。

app/avatar_uploader.rb
# encoding: utf-8
class AvatarUploader < CarrierWave::Uploader::Base

  include Cloudinary::CarrierWave

  process :convert => 'png'
  process :tags => ['avatar']

  version :standard do
    process :resize_to_fill => [100, 150, :north]
  end

  version :thumbnail do
    process :resize_to_fit => [50, 50]
  end

  def public_id
    return model.id ・・・※1
  end

end

※1 public_idでCloudinaryから画像を参照できるので、都合のいい値を設定すれば便利です。UserのAvatarならUser.idが良いと思います。

user.rbを編集

uploaderとUserモデルを関連付けます。

app/models/user.rb
class User < ActiveRecord::Base
  attr_accessible :avatar, :avatar_cache, :name, :remove_avatar

  mount_uploader :avatar, AvatarUploader

end

database.ymlを追加

忘れないうちにファイルを追加しておきましょう。先ほどダウンロードした、cloudinary.ymlconfigフォルダに保存します。database.ymlと同じ階層です。

new.html.erbとedit.html.erbの編集

Scaffoldで作成されたviewのnew.html.erbedit.html.erbは、_form.html.erbを共有しているので、_form.html.erbを編集します。

app/views/_form.html.erb
<%= form_for(@user) do |f| %>
  <% if @user.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
      <% @user.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>
  <div class="field">
        <%= image_tag(@user.avatar_url(:thumbnail), :width => 80, :height => 80) %>
        <%= f.file_field :avatar %>
        <%= f.check_box :remove_avatar %> 画像を削除する
        <%= f.hidden_field :avatar_cache %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

index.html.erbとshow.html.erbの編集

index.html.erbは名前だけ表示。

app/views/users/index.html.erb
<h1>Listing users</h1>

<table>
  <tr>
    <th>Name</th>
    <th></th>
    <th></th>
    <th></th>
  </tr>

<% @users.each do |user| %>
  <tr>
    <td><%= user.name %></td>
    <td><%= link_to 'Show', user %></td>
    <td><%= link_to 'Edit', edit_user_path(user) %></td>
    <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New User', new_user_path %>

show.html.erbは名前と画像だけ表示

app/views/users/show.html.erb
<p id="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @user.name %>
</p>

<p>
  <b>Avatar:</b>
  <%= image_tag(@user.avatar_url) %>
</p>


<%= link_to 'Edit', edit_user_path(@user) %> |
<%= link_to 'Back', users_path %>

画像のリサイズなどはCloudinaryでいろいろと提供されていますので、試してみて下さい。
http://cloudinary.com/documentation/image_transformations

では、Herokuへpushします。

console
$git init  gitの初期化 最初だけ
$git add .
$git commit -m 'first commit'
$git push heroku master

Herokuを開いてみましょう。

console
$heroku open

これで、画像の表示、アップロード、削除ができるアプリの完成です。


画像リサイズは、Rmagikやminimagikなどを利用したり(私はこれに超絶ハマりました^^;)
画像ストレージは、AWSのS3を利用したりなど、色々とハードルが高いですが、
この方法は比較的手軽に活用できるのではないかと思います。
ぜひぜひお試しください!これが無料で使えるというのがすごいですね。。


via http://cloudinary.com/documentation/rails_integration
via https://github.com/jnicklas/carrierwave

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away