酒と泪とRubyとRailsと

Ruby on Rails と Objective-C は酒の肴です!

Carrierwave/Mongoid/Herokuで作るRails画像アップロード機能

Rails3.29/Heroku/Mongoid環境に画像アップロードの実装するために、「Carrierwave」を利用しました。その一連の流れを忘備録で書いておきます。

fpu_tmp_1353917850.012_128a26

Demo Source(GitHub)

Carrierwaveって何?

Carrierwaveは、シンプルで柔軟性の高いファイルアップロードアプリです。 Ruby on RailsなどのRackベースのアプリに組み込めます。

競合のGemとしては、「Paperclip」が挙げられます。現時点ではPaperclipのほうが人気は高いですが、扱いやすくて負けないくらい多機能です。

Mongoid + ImageMagickのインストール

もし、MacでMongoDBのインストールがまだの場合は、 MongodbをHomebrew/Mac Lionでインストール を良かったら見てください。

続いて、Carrierwaveを動かすために、ローカルテスト用にImageMagickをインストール(Mac Homebrewの場合)。

コンソール
1
brew install imagemagick

Rails プロジェクト作成

プロジェクトを作成する。今回はmongoidを利用するので、ActiveRecordをスキップ(-Oオプションを付ける)する。

コンソール
1
rails new test-app --skip-test-unit -O

Gitリポジトリ作成を作成します。

コンソール
1
2
3
git init
git add -A
git commit -m "create new project"

Gemfileファイルに以下のGemを追加

Gemfile
1
2
3
4
5
6
7
8
9
10
11
12
13
ruby '1.9.3'

# Haml
gem 'haml-rails'

# Mongoid
gem 'mongoid'
gem 'bson_ext'
gem 'origin'
gem 'moped'
gem 'rmagick', :require => 'RMagick'
gem 'carrierwave'
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'

Gemfileの設定を反映。

コンソール
1
bundle install

mongoDBに接続するための設定を作成

コンソール
1
rails generate mongoid:config

config/mongoid.ymlでProductionの設定をします。 こちらは後で使うHeroku アドオンMongoLab用の設定です。

コンソール
1
2
production:
  uri: <%= ENV['MONGOLAB_URI'] %>

Carrierwaveの設定

application.rbの更新。

config/initializers/carrierwave.rb
1
2
3
4
5
CarrierWave.configure do |config|
  config.storage = :grid_fs
  config.grid_fs_connection = Mongoid.database
  config.grid_fs_access_url = "/images"
end

アップローダー/Scaffoldの修正

アップローダーのひな形の生成。

コンソール
1
2
rails g scaffold article title:string
rails g uploader thumbnail

モデルファイル「app/model/article.rb」に以下を追加。

app/model/article.rb
1
2
include Mongoid::Timestamps
mount_uploader :thumbnail, ThumbnailUploader

アップローダーファイル「app/uploader/thumbnail_uploader.rb」の修正。

app/uploader/thumbnail_uploader.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
require "digest/md5"
class ThumbnailUploader &lt; CarrierWave::Uploader::Base
  include CarrierWave::RMagick # コメントを解除

  storage :grid_fs

  def store_dir
    "images/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  version :mini do
    process :resize_to_limit => [200, 200]
  end
end

コントローラファイル「add/controller/articles_controller.rb」の修正。

add/controller/articles_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class ApplicationController < ActionController::Base
  protect_from_forgery

  def image
    gridfs_path = env["PATH_INFO"].gsub("/images/", "")
    begin
      gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r')
      self.response_body = gridfs_file.read
      self.content_type = gridfs_file.content_type
    rescue
      self.status = :file_not_found
      self.content_type = 'text/plain'
      self.response_body = ''
    end
  end
end

Viewファイル「app/views/articles/_form.html.haml」の修正。

app/views/articles/_form.html.haml
1
2
3
= image_tag( @article.thumbnail_url ) if @article.thumbnail?
= f.file_field :thumbnail
= f.hidden_field :thumbnail_cache

Viewファイル「app/views/pages/show.html.haml」の修正。

vim app/views/pages/show.html.haml

コンソール
1
= image_tag( @article.thumbnail_url(:mini))

routeファイルを修正。

config/routes.rb
1
2
root :to => "articles#index"
match "/images/uploads/*path" => "application#image" #thumbnail画像

HerokuにPush

今回はHerokuとMongoDBのアドオン”MongoLab”を追加します。

コンソール
1
2
3
git add -A
git commit -m "add scaffold/uploader"
heroku create test-app --stack cedar

MongoLabのAddonを追加。

コンソール
1
heroku addons:add mongolab:starter

結果をブラウザで確認。

fpu_tmp_1353971612.7499_ff3902

補足

Mongoidは2.xx系と3.xx系でかなり設定方法が変更されています。 当初3.xx系で組み込みに挑戦しましたが、DBからのimage取得周りでどうしても手詰まりになり、 2.xx系を使った形にしています。技術力&知識がついたら3.xx系で再チャレンジしたいと思っています!

Special Thanks

herokuで無料のimage uploaderを作る

Rails3での画像アップロードの実装(ImageMagick + Rmagick + file_column)

[Rails] file_column から CarrierWave へ (序)

jnicklas / carrierwave GitHub

jnicklas / carrierwave-mongoid GitHub

テスト環境

# OS : Mac Lion(OS X 10.7)
# Rails : 3.2.9
# ImageMagic : 6.7.7-6.lion
# Gem Rmagick : 2.13.1
# Gem carrierwave : 0.6.2
# Gem mongoid : 2.4.12
# Gem carrierwave-mongoid : 0.2.1

おすすめの書籍