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に以下を追記


gem 'mongoid', '~>2.1'
gem 'bson_ext', '~>1.3'
gem 'carrierwave'
gem 'carrierwave-mongoid', :require => 'carrierwave/mongoid'


# bundle install

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

config/mongoid.ymlのproductionを以下のように修正

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



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

以下を記述

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


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

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


class User
include Mongoid::Document
field :title, :type => String
mount_uploader :photo, PhotoUploader
end


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


# encoding: utf-8
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::RMagick
storage :grid_fs
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
version :thumb do
process :resize_to_limit => [200, 200]
end
end


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



<%= f.label :photo %>

<%= image_tag( @user.photo_url ) if @user.photo? %>
<%= f.file_field :photo %>
<%= f.hidden_field :photo_cache %>



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


require 'mongo'
class UsersController < ApplicationController
def serve
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


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 件のコメント:

コメントを投稿