2010年11月21日

Herokuに画像をアップロードする Rails 3 + Paperclip + Amazon S3

Heroku上で作成中のアプリに画像をアップロードできる機能を追加したいと思い挑戦してみました。
    調査結果:
  • HerokuはRead-onlyなので、Herokuのファイルシステムには画像はアップロードできなさそう
  • 代わりにHerokuの公式サイトではAmazon S3をストレージとして利用することを推奨している
  • また同じページにはAttachment-Fu か Paperclipプラグインを利用することが簡単だろうとのこと
  • 実際にHeroku + Paperclip + Amazon S3を利用した構築方法が以下のサイトで公開されている
    http://webtempest.com/how-to-allow-image-uploads-in-rails-on-heroku/
ということで、私もHeroku + Paperclip + Amazon S3で作ってみたいと思います。

Amazon S3
まず気になる利用料。せっかくHerokuを使って無料アプリを作っているので、あまりお金をストレージにつぎ込みたくないというのが本音です。で、Amazonのページで確認すると、
  • ストレージ: 月額料金 $0.140/GB
  • 低冗長化ストレージ: 月額料金 $0.093/GB
  • データ転送:全てのデータ受信: $0.100 /GB
  • リクエスト: $0.01/1,000リクエスト
という何とも信じられない親切な値段設定(2010年11月21日現在)。サイトの人気が出ない限りは1GBにたどり着くのに何年もかかるだろうから毎月100円以下で当面はすみそうです。

ということで、さっそく申込みしてみます。
同じページにある「Amazon S3の利用を申し込む」ボタンを押します。
ログインページでログインします。
次のページで値段を確認して、クレジットカード情報を入力します。
住所を確認します。
最後にサマリーページが表示されるので、ここで確認をして「Complete Sign Up」ボタンを押すと申し込みが完了です。
しばらくするとAmazonからメールが届くので、そこに書いてあるリンクをクリックしてページにログインすると、利用するために必要なAccess Keysなどの情報が確認できます。
これで基本的な申し込みは完了しました。

S3にアクセスするためにFireFoxのプラグインであるAmazon S3 Organizer(S3Fox)をインストールします。
S3Foxの利用方法は動画で公開されています。英語だけど動画なのでわかりやすいです。
FireFoxを再起動後、ツールメニューのS3 OrganizerをクリックするとS3 Organizerが起動するので、Manage Accountsボタンをクリックし、先ほどAmazonで入手した情報を入力します。
さっそく試しにファイルをアップロードしてみようとしたところ、Bucketの選択ダイアログが開いたので、いったんキャンセルをします。
Create Bucket/Directoryボタンを押してBucketを作成します。Bucketの名前にはいろいろなルールがあるようなのですが、S3の中でユニークである必要があるようです。そしてここで付けた名前がそのままファイルにアクセスする際のURIに利用されるので、それを意識して名前を付けるのが良いです。
先ほど作成したBucketにファイルをUploadしてみます。Uploadに成功したらファイルのアクセス権を設定します。ファイルの上で右クリックして、Edit ACLを選択します。EveryoneのReadにチェックしてみました。確認のために再びファイルの上で右クリックして、Copy URL to Clipboardをクリックし、ブラウザのアドレスバーに貼り付けます。無事ファイルが表示されました。
以上でS3の設定が完了です。

なおS3へのアクセス方法やBucketについては、こちらのエントリーが参考になります。
http://www.labnol.org/internet/tools/amazon-s3-simple-storage-service-guide/3889/
http://www.labnol.org/internet/tools/amazon-s3-buckets-tutorial/3890/


Paperclip
ここからはPaperclipとS3を連携させてみたいと思います。
まずはRailsのアプリ(s3paperclip)を作成します。
$ rails new s3paperclip
$ cd s3paperclip

アプリルートのGemfileに以下の二行を追加し(今回はDBにsqlite3を利用)、インストールを行います。
gem 'sqlite3-ruby'
gem 'paperclip'

$ bundle install

Productモデルを作成し、画像を持つことにします。画像はphotoという呼び名にしておきます。
$ rails g scaffold product name:string
Productモデルを以下のように編集します。
class Product < ActiveRecord::Base 
has_attached_file :photo,
:styles => {
:thumb => "100x100",
:medium => "200x200",
:large => "600x400"
}
end
さらにS3に保存するために以下のように編集します。
class Product < ActiveRecord::Base 
has_attached_file :photo,
:styles => {
:thumb => "100x100",
:medium => "200x200",
:large => "600x400"
},
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension"
end
#{RAILS_ROOT}/configに、s3.ymlというファイルを作成し以下のように記述します。
development:
bucket: myappdevelopment
access_key_id: your key
secret_access_key: your key

test:
bucket: myapptest
access_key_id: your key
secret_access_key: your key

production:
bucket: myapp
access_key_id: your key
secret_access_key: your key
※bucketやyour keyの部分は環境に合わせて定義が必要です。

gemファイルにAmazon S3用の記述を追加します。
gem 'aws-s3'
インストールします。
$ bundle install

DBに画像の情報を記録できるようにProductsテーブルを書き換えます。
これはマイグレーション用のスクリプトを作成して行います。
$ rails g migration add_photo_columns_to_product
作成されたdb/migrate/(Date)_add_photo_columns_to_product.rbを以下のように編集します。
class AddPhotoColumnsToProduct < ActiveRecord::Migration
def self.up
add_column :products, :photo_file_name, :string
add_column :products, :photo_content_type, :string
add_column :products, :photo_file_size, :integer
add_column :products, :photo_updated_at, :datetime
end

def self.down
remove_column :products, :photo_file_name
remove_column :products, :photo_content_type
remove_column :products, :photo_file_size
remove_column :products, :photo_updated_at
end
end
マイグレーションをします。
$ rake db:migrate

formビューを書き換えます。
(1行目を書き換え)
<%= form_for @product , :html => { :multipart => true } do |f| %>

(form内に追記)
<%= f.file_field :photo %>

showビューを書き換えます。
<%= image_tag @product.photo.url %>
<%= image_tag @product.photo.url(:medium) %>
<%= image_tag @product.photo(:thumb) %>
<%= image_tag @product.photo(:large) %>

gitにコミットします。
$ git init
$ git add -A
$ git commit -m "new app"

Herokuにアプリを配置します。
$ git push heroku master

DBをマイグレートします。
$ heroku rake db:migrate

以上で画像ファイルがHerokuにアップロードできるようになりました。
注意点としては、ローカルの開発環境にImgamagicがインストールされていないと、正常に動作しない点ですね。Heroku上では正常に動作します。

追記:
Windowsで動作できるようにRails 3 WindowsでPaperclipを使えるようにするを書きました。
posted by まーつん at 22:02| Comment(0) | TrackBack(0) | Ruby on Rails | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/170193214

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。