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


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

Demo
Source(GitHub)


🗻 CarrierWaveって何?

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

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

🐯 Mongoid + ImageMagickのインストール

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

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

brew install ImageMagick

🐞 Rails プロジェクト作成

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

rails new test-app --skip-test-unit -O

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

Git init
Git add -A
Git commit -m "create new project"

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

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の設定を反映。

bundle install

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

rails generate mongoid:config

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

production:
uri: <%= env['MONGOLAB_URI'] %>

🐰 Carrierwaveの設定

application.rbの更新。

CarrierWave.configure do |config|
config.storage = :grid_fs
config.grid_fs_connection = Mongoid.database
config.grid_fs_access_url = "/images"
end

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

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

rails g scaffold article title:string
rails g uploader thumbnail

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

include Mongoid::Timestamps
mount_uploader :thumbnail, ThumbnailUploader

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

require "digest/md5"
class ThumbnailUploader < 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」の修正。

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」の修正。

= image_tag( @article.thumbnail_url ) if @article.thumbnail?
= f.file_field :thumbnail
= f.hidden_field :thumbnail_キャッシュ

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

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

= image_tag( @article.thumbnail_url(:mini))

routeファイルを修正。

root :to => "articles#index"
match "/images/uploads/*パス" => "application#image" #thumbnail画像

😀 HerokuにPush

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

git add -A
git commit -m "add scaffold/uploader"
heroku create test-app --stack cedar

MongoLabのAddonを追加。

Heroku addons:add mongolab:starter

結果をブラウザで確認。

🏈 補足

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

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍