1

フラッシュウィジェットからRailsアプリケーションにファイルをアップロードしようとしています。このアプリケーションはattachment_fuを使用して更新された画像を処理します。複数のファイルを簡単に選択してアップロードできるため、アップロードにフラッシュを使用しています。ただし、railsコントローラーsave!が新しく作成されたActiveRecordオブジェクトを呼び出そうとすると、このエラーが発生します。

ActiveRecord::RecordInvalid (Validation failed: Content type is not included in the list):
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/validations.rb:946:in `save_without_transactions!'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:112:in `save!'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/connection_adapters/abstract/database_statements.rb:66:in `transaction'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:80:in `transaction'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:100:in `transaction'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:112:in `save!'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:120:in `rollback_active_record_state!'
    /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/transactions.rb:112:in `save!'
    /app/controllers/photos_controller.rb:13:in `create'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `send'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/base.rb:1158:in `perform_action_without_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:697:in `call_filters'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/filters.rb:689:in `perform_action_without_benchmark'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'

そのため、コンテンツタイプが正しく送信されていないようです。実際のところ、Flashは(この特定のテストケースの場合)application/octet-stream予想されるコンテンツタイプのを送信しています。image/png

アップロードを実行するActionScript3.0コードは次のようになります。

var request:URLRequest = new URLRequest(paramObj.serverUrl + "/albums/" + paramObj.albumId + "/photos");
var variables:URLVariables = new URLVariables();
variables["photo[title]"] = file.name;
variables["authenticity_token"] = paramObj.authenticity_token;
variables["commit"] = "Upload Photo";
request.data = variables;
request.method = URLRequestMethod.POST;
file.upload(request, 'photo[uploaded_data]');

フォームパラメータはすべて、通常のブラウザアップロードから期待されるFlashアップロードに存在します。パケットスニファを実行した後、私が見ることができる唯一の本当の違いは、コンテンツタイプが異なることです。

モデルはattachment_fuを使用し、次のようになります。

class Photo < ActiveRecord::Base
  belongs_to :album

  has_attachment :content_type => :image, 
                 :storage => :file_system, 
                 :max_size => 10.megabytes, 
                 :thumbnails => { 
                   :thumb  => '100x100>',  
                   :large  => '800x600>', 
                 } 

  validates_as_attachment
end

では、フラッシュが送信するコンテンツタイプを修正するにはどうすればよいですか?また、attachment_fuは、マジックナンバーなどを使用して独自に決定するのではなく、ブラウザから送信されたコンテンツタイプを信頼するのはなぜですか?

:content_type => :imageまたはを削除した場合validates_as_attachment、またはコントローラーを呼び出しに変更した場合save(false)、オブジェクトは作成されますが、attachment_fuは画像のサイズを変更する役割を果たしません。

4

1 に答える 1

5

残念ながら、Flashアップロードは常にコンテンツタイプ「application/octet-stream」で送信されます。おそらく最も簡単な回避策は、mimetype_fuを使用してbefore_validationコールバックの mimetypeを推測することです。ペーパークリップには、この機能が組み込まれています。

別のオプションは、is_imageを上書きすることです。画像プロセッサを使用して、ファイルが画像であるかどうかを実際に判断します(たとえば、rmagickでは、ファイルを開いて、レイヤーがあるかどうかを確認できます)。これは間違いなくより多くのリソースを消費するソリューションですが、処理できるすべてのファイルを受け入れ、他のファイルは受け入れないようにします。

于 2009-05-08T15:25:23.707 に答える