LoginSignup
27
26

More than 5 years have passed since last update.

Rails4+MongoDB+Herokuでサイトのサムネイル画像を保存・参照する方法

Posted at

概要

画像を生成するライブラリはいくつかありますが、調べた中で一番簡単に実装できた方法を紹介します。

前提として無料でサービスを公開できることを目指した結果、PaasはHeroku、画像はHerokuのMongoDB(最大50MB)にBinaryデータとして画像を保存することにしました。

他に候補としてAmazonS3などがありますが、アクセス数(転送データ量)に応じて従量課金されるので外しました。本格的にサービスを作るならS3やレンタルサーバなどを借りた方がいいかと思います。

構成

  • Ruby2.1.1
  • Rails4.0.4
  • MongoDB

Railsの実装

railsの基本的なアプリの作り方は省きます。Mongoidを使う上での注意点として、rails newするときにActiveRecordを含めないよう、-Oオプションを指定します。

Mongoid

Gemfileに以下を追加します。Rails4.xを使う場合、Mongoidも4.xを使う必要があります。現時点では4.0.0.beta1が最新なので、バージョンを指定します。また、Binaryオブジェクトを使うため、bsonとmopedも追加します。

gem 'mongoid', '4.0.0.beta1'
gem "bson"
gem "moped", github: "mongoid/moped"

参考:http://rubygems.org/gems/mongoid

Mongoidの4.xでMoped::BSONを使うために、config/application.rb に以下の記述を追加する必要があります。

require "bson"
require "moped"

Moped::BSON = BSON

参考:https://github.com/mongoid/mongoid/issues/3455

IMGKit

スクリーンショットを作成するためのライブラリはいくつかありますが、導入が簡単そうで、Herokuでも使用できることからIMGKitを使うことにします。

Mac上で使う場合は、wkhtmltoimageをダウンローとして/usr/local/binに置きます。(パスが通ればどこでもいいです。)

参考:http://weble.org/2012/06/01/mac-wkhtmltoimage
参考:https://github.com/csquared/IMGKit

画像の保存と参照

Modelのfieldには、type: Moped::BSON::Binary を指定します。これでBinaryデータが保存できます。

class Site
  include Mongoid::Document
  field :thumb, type: Moped::BSON::Binary
  ...
end

保存するためのControllerの処理は、以下のようにします。

def create
  img = IMGKit.new("http://example.com", quality: 50)
  site = Site.new
  site = Moped::BSON::Binary.new(img.to_img)
  site.save
  ...
end

参照は /img/(:id) のURLで取得したいので、以下のようにします。保存するfieldはthumbですが、取得するときはthumb.dataになることに注意してください。また、アクセスのたびにDBにアクセスするのは効率が悪いので、2回目以降はキャッシュを使うようにするといいと思います。

def img
  site = Site.find(params[:id])
  img = site.thumb.data if site.try(:thumb)
  send_data(img, filename: "#{site._id}.jpg", type: "image/jpeg", disposition: "inline")
end

参考:http://mongoid.org/en/mongoid/docs/documents.html
参考:https://github.com/csquared/IMGKit
参考:http://railsdoc.com/references/send_data

Herokuにデプロイする際の設定

Rails4

Rails3までと4では、設定が少し変わっていましたので、公式のドキュメントを参照しました。Gemfileに以下が必要となります。

ruby "2.1.1" # 使用するRubyのバージョン
gem 'rails_12factor', group: :production

参考:https://devcenter.heroku.com/articles/getting-started-with-rails4

Mongoid

config/mongoid.yml にproductionの設定を追加します。書き方はMongoid 3.xと同様で動きました。

production:
  sessions:
    default:
      uri: <%= ENV['MONGOHQ_URL'] %>

参考:https://devcenter.heroku.com/articles/mongohq#mongohq-replica-sets

IMGKit

./bin に wkhtmltoimage-amd64 を配置し、gitのリポジトリに追加します。

IMGKit.configure do |config|
  config.wkhtmltoimage = Rails.root.join('bin', 'wkhtmltoimage-amd64').to_s if ENV['RACK_ENV'] == 'production'
end

参考:https://github.com/csquared/IMGKit
参考:http://log.miraoto.com/2012/07/632/

日本語が化ける

heroku上でスクリーンショットを取ると、日本語の文字が正しく表示されません。これを防ぐには、fontファイルを/.fontsに配置してgitリポジトリに追加すればOKです。fontファイルはAPIフォントを利用しました。

参考:http://qiita.com/ssuzuki@github/items/58be855f909f29c05ae6
参考:http://d.hatena.ne.jp/shinichitomita/20120519/1337479457
参考:http://ipafont.ipa.go.jp/

27
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
26