2012年3月18日日曜日

herokuで無料のimage uploaderを作る

herokuで無料のimage uploaderを作る

herokuは非常に便利ですが、read onlyなのでアップローダーを作ったりできません。
もしやろうとするとS3を使った方法が一般的のようですが、若干利用料金がかかってしまいます。
なので無料で作れる方法を考えてみました。

herokuでは画像を直接アップすることはできませんが、DBに直接保存することができます。
しかしherokuのデフォルトのものは、5MBしかありません。
そこでmongolabという、mongodbを240MBまで無料提供してくれるサービスを利用します。
なおmongolabはherokuにadd-onとして提供されているため、セットアップは簡単です。

githubにファイルをあげておいたので、参考にしてください。
https://github.com/face-do/heroku-image-uploader

まずはrailsプロジェクトを作成します。
ただしmongodbを使うため、active recordを切るようにしておきます。

# rails new uploader -O

次に、gemfileに以下を追記

  1. gem 'mongoid''~>2.1'  
  2.   
  3. gem 'bson_ext''~>1.3'  
  4.   
  5. gem 'carrierwave'  
  6.   
  7. gem 'carrierwave-mongoid':require => 'carrierwave/mongoid'  


# bundle install

で、mongodbに接続するための設定のひな形を作る。
# rails generate mongoid:config

config/mongoid.ymlのproductionを以下のように修正
  1. production:  
  2.   
  3.   uri: <%= ENV['MONGOLAB_URI'] %>  



carrierwaveの設定をする
#vim config/initializers/carrierwave.rb

以下を記述
  1. CarrierWave.configure do |config|  
  2.   
  3.   config.storage = :grid_fs  
  4.   
  5.   config.grid_fs_connection = Mongoid.database  
  6.   
  7.   config.grid_fs_access_url = "/images"  
  8.   
  9. end  


アップローダのひな形を作る
# rails g scaffold page title:string
# rails g uploader photo

app/models/user.rbは以下のように

  1. class User  
  2.   
  3.   include Mongoid::Document  
  4.   
  5.   field :title:type => String  
  6.   
  7.   mount_uploader :photo, PhotoUploader  
  8.   
  9. end  


app/uploaders/photo_uploader.rbは以下のように修正

  1. # encoding: utf-8  
  2.   
  3. class PhotoUploader < CarrierWave::Uploader::Base  
  4.   
  5.   include CarrierWave::RMagick  
  6.   
  7.   storage :grid_fs  
  8.   
  9.   def store_dir  
  10.   
  11.     "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"  
  12.   
  13.   end  
  14.   
  15.   version :thumb do  
  16.   
  17.     process :resize_to_limit => [200, 200]  
  18.   
  19.   end  
  20.   
  21. end  


app/views/users/_form.html.erbの
の上に以下を追記

  1. <div class="field">  
  2.   
  3.   <%= f.label :photo %>  
  4.   
  5.   
  6.   <%= image_tag( @user.photo_url ) if @user.photo? %>  
  7.   
  8.   <%= f.file_field :photo %>  
  9.   
  10.   <%= f.hidden_field :photo_cache %>  
  11.   
  12. </div>  


このままだと画像が表示されないので、画像表示用のメソッドを作る。
まずはapp/controllers/users_controller.rbに以下を追記

  1. require 'mongo'  
  2.   
  3. class UsersController < ApplicationController  
  4.   
  5.   def serve  
  6.   
  7.     gridfs_path = env["PATH_INFO"].gsub("/images/""")  
  8.   
  9.     begin  
  10.   
  11.       gridfs_file = Mongo::GridFileSystem.new(Mongoid.database).open(gridfs_path, 'r')  
  12.   
  13.       self.response_body = gridfs_file.read  
  14.   
  15.       self.content_type = gridfs_file.content_type  
  16.   
  17.     rescue  
  18.   
  19.       self.status = :file_not_found  
  20.   
  21.       self.content_type = 'text/plain'  
  22.   
  23.       self.response_body = ''  
  24.   
  25.     end  
  26.   
  27.   end  


config/routes.rbに以下を追記
match "/images/uploads/*path" => "users#serve"

これでアプリ側の設定は終了。git でcommitしておきます。
# git add .
# git commit -m 'first commit'

次にheroku側の設定をします。
#heroku create --stack cedar
#heroku addons:add mongolab:starter

あとはherokuにdeployするだけ
#git push heroku master

0 件のコメント:

コメントを投稿