おおいしつかさ


旅行とバイクとドライブと料理と宇宙が好き。
Ubie Discoveryのプログラマ。
Share:  このエントリーをはてなブックマークに追加

AmazonS3(Tokyo region) + Paperclip + Rails3を使ってみた

将来、Heroku等のクラウド環境へ移行することも踏まえて、画像ファイルをAmazonS3に置くようにしました。ちょうど最近、「 AWSの新しい アジアパシフィック東京リージョンが利用可能になりました!」という話題もあったので、さっそく東京リージョンを使ってみます。
さらに今まではImageScienceで画像のサムネイル作成処理をやっていましたが、Paperclipを使ってみることにしました。
ついでに、このブログ自体もRails2からRails3.0.5をベースにして作り直すことにしました。

AmazonS3の説明はあちらこちらに豊富に存在しているので割愛しますが、オンラインストレージサービスのようなものです。アップロードしたデータはHTTP経由でもアクセス可能なので、web上の画像ファイルを扱うにはもってこいだと思います。

AmazonS3の利用を開始したら、Bucketを作成します。 AWS Management Consoleを使えば簡単に作成できます。Bucketとは名前空間の役割を果たす、フォルダのようなものです。
kaeruspoonでは開発用と本番用でふたつのBucketを作成しました。
これらの設定値はconfig/s3.ymlに保存します。

development:  
  access_key_id: アクセスキー  
  secret_access_key: シークレットアクセスキー  
  bucket: kaeruspoondevelopment  

test:  
  access_key_id: アクセスキー  
  secret_access_key: シークレットアクセスキー  
  bucket: kaeruspoondevelopment  

production:  
  access_key_id: アクセスキー  
  secret_access_key: シークレットアクセスキー  
  bucket: kaeruspoon  

画像のアップロード&サムネイル作成を簡単にやってくれるのがPaperclipです。簡単すぎて涙が出そうなくらいすばらしいライブラリです。
GemfileにPaperclipを使用します。AmazonS3と連携させるため、aws-s3というライブラリも追加します。

gem "paperclip"  
gem 'aws-s3'  

ちなみみにPaperclipはImageMagickを利用しているので、まずImageMagickをインストールしておく必要があります。(RMagickは必要ありません)。

bundle install を行ったら、画像を取り扱うモデルにPaperclipの設定を行います。ここでは、Photoモデルを対象とします。

class Photo < ActiveRecord::Base  
  has_attached_file :image,  
    :styles => {  
      :large => "600x600",  
      :medium => "320x320",  
    },  
    :storage => :s3,  
    :s3_credentials => "#{Rails.root}/config/s3.yml",  
    :url  => ":s3_domain_url",  
    :path => ":attachment/:id/:style.:extension"  
end  

has_attached_fileの第一引数は、画像を扱うため際のプロキシの役割を果たす名前となります。
:styleで作成するサムネイルの名前と大きさを指定します。長辺がこのサイズに合わされます。指定したサイズぴったりにしたい場合は、”100x100#”というように最後に#を指定してあげます。
その下がAmazonS3との連携の設定となります。AmazonS3のHTTPアクセス時のURLによりますが、おそらくほとんどの場合は、:url => “:s3_domain_url”を指定してあげれば問題ないと思います。

また、Paperclipを使う際には、対象のモデルが以下のカラムを持っていなければなりません。
各カラム名の最初についているimageは、has_attached_fileの第一引数で指定したアタッチメント名です。アタッチメント名が違えば、カラム名も異なります。

      t.string :image_file_name, :null => false  
      t.string :image_content_type, :null => false  
      t.integer :image_file_size, :null => false  
      t.datetime :image_updated_at  

今回はAmazonS3の東京リージョンを使用しているので、まだ設定が必要になります。このままだと、ファイルのアップロードができません。東京リージョンのデフォルトドメインを指定してあげる必要があります。
config/initializers/aws.rb などのファイルを作成して、以下の内容を書き込みます。

require 'aws/s3'  
AWS::S3::DEFAULT_HOST.replace "s3-ap-northeast-1.amazonaws.com"  

ここまでできれば、あとは使うだけです。画像ファイルのアップロードは以下のように行います。

  <%= form_for Photo.new, :html => { :multipart => true } do |f| %>  
    <%= f.file_field :image %>  
    <%= submit_tag "アップロード" %>  
  <% end %>  

コントローラでは以下のように保存します。

Photo.create!(params[:photo])  

これだけで、各サムネイルの作成からAmazonS3へのファイルのアップロードまですべて完了します。素晴らしいです。

実際に画像を表示したいときは以下のようにします。

<%= image_tag photo.image.url(:medium) %>  

urlメソッドの引数で表示したい画像の大きさを指定します。:originalとすると、アップロードした画像が表示されます。