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

  • 64
    Like
  • 0
    Comment
More than 1 year has 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