«

»

7月
24

[RoR]rest-clientでpaperclipに対応した画像フォーム送信を再現してみる

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に追記。

gem 'paperclip'

bundle installの実行。

$ 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="&#x2713;" /></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

コメントを残す

メールアドレスは公開されません

次の HTMLタグおよび属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>