in a state of ease: Herokuに画像をアップロードする Rails 3 + Paperclip + Amazon S3 http://wine4u.seesaa.net/article/170193214.html
こちらの記事を参考に、Rails3にPaperclipを導入して画像をアップロードするrailsプロジェクトを作ってみたので、その時の健忘録。
ひとまず今回はAWS S3は割愛する事にしてシンプルにrails3にPaperclipのみを導入してみる。
Gemfileに追記。
bundle installの実行。
なお、ruby1.9.2以上でないと次の通りエラーメッセージが出てしまい最新版(3.0〜)は導入できない。
Gem::InstallError: paperclip requires Ruby version >= 1.9.2.
An error occured while installing paperclip (3.1.4), and Bundler cannot continue.
Make sure that `gem install paperclip -v '3.1.4'` succeeds before bundling. |
このような場合(ruby1.8系等)は ~>2.7を指定する。
gem 'paperclip', '~> 2.7' |
bundle installし直すと無事インストールできる。
そして、記事の通りproductというモデルとそのコントローラーをscaffoldで自動生成し、
migration、modelやpartial view、等いくつかの変更を加える。
変更が済んだら、$rails s で起動して新規登録画面をブラウザで確認する。
名称と画像を登録すると、添付画像が指定のサイズ通り加工されサーバサイドに保存される。
なお、開発環境をクライアント・サーバとする場合は、ImageMagickが事前にインストールされている必要がある。OSXではHomebrewやMacPortsで導入する。Winは試していない。
このようにPaperclipを使うと非常に簡単に添付画像の保存、DBへの登録ができるようだ。
rest-clientで新規登録時のPOST送信を再現してみる
この新規登録フォームからのPOST送信をブラウザ経由でなくrest-clientで送信した場合、
どのように記述すれば同様の事ができるか試してみた。
なお、Rails側のモデルのクラス、およびテーブルは次のようになっている。
project.rb
class Product < ActiveRecord::Base
has_attached_file :photo,
:styles => {
:thumb => "100x100",
:medium => "200x200",
:large => "600x400"
}
end |
モデル: product
添付ファイル: photo
schema.rb
create_table "products", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.string "photo_file_name"
t.string "photo_content_type"
t.integer "photo_file_size"
t.datetime "photo_updated_at"
end |
テーブル: products
カラム(画像メタ情報関連): photo_*
カラム(テキスト関連): name
次にscaffoldで作成した登録フォームのHTMLを確認する。
scaffoldで生成したproductsの登録フォーム部分( http://127.0.0.1:3000/products/new 等)
<h1>New product</h1>
<form accept-charset="UTF-8" action="/products" class="new_product" enctype="multipart/form-data" id="new_product" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /></div>
<div class="field">
<label for="product_name">Name</label><br />
<input id="product_name" name="product[name]" size="30" type="text" /><br />
<input id="product_photo" name="product[photo]" type="file" /><br />
</div>
<div class="actions">
<input name="commit" type="submit" value="Create Product" />
</div>
</form> |
HTMLの内容から、
メソッド:POST
MIMEタイプ:multipart/form-data
プロジェクト名:product[name]
添付ファイル:product[photo]
という構造であれば、シミュレートできそうである事がわかる。
試行錯誤した結果、次のような記述にすれば、再現できる模様。
これに対応するrest-clientでの送信例(functionalテストでの記述例)
test "create a project via rest-client" do
request = RestClient::Request.new(
:method => :post,
:url => "http://127.0.0.1:3000/products/",
:payload => {
:multipart => true,
:product => {
:name => "test_via_restclient",
:photo => File.new("test/image/test.png")
}
})
response = request.execute
end |
なお、CSRF検証は外して実施している。
class ProductsController < ApplicationController
skip_before_filter :verify_authenticity_token # allow CSRF |
参考
http – Ruby rest-client file upload as multipart form data with basic authenticaion – Stack Overflow http://stackoverflow.com/questions/11388090/ruby-rest-client-file-upload-as-multipart-form-data-with-basic-authenticaion