kaeruspoon

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

76de73a1dae79a86bb99a813bd8e8e0a?s=30&d=http%3a%2f%2fkaeruspoon%.net2f2014%2fimages%2fno imageTsukasa OISHI

将来、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とすると、アップロードした画像が表示されます。