Por que não meu carregamento do Flash para Rails e trabalho attachment_fu (que tem algo a ver com o tipo de conteúdo)?
-
10-07-2019 - |
Pergunta
Eu estou tentando fazer upload de um arquivo de um widget de flash para a minha aplicação rails, que usa attachment_fu para lidar com imagens uplaoded. Eu estou usando flash para fazer upload, uma vez que torna mais fácil para selecionar e enviar vários arquivos. No entanto, eu estou recebendo este erro quando os trilhos tentativas controlador para save!
chamada no objeto ActiveRecord recém-criado:
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'
Assim, parece que o tipo de conteúdo não está sendo enviado corretamente. Por uma questão de fato, o Flash está enviando um tipo de conteúdo de application/octet-stream
, onde eu esperava que fosse image/png
(para este caso de teste particular).
Meu código do ActionScript 3.0 que executa os olhares de upload como este:
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]');
Os parâmetros de formulário estão todos presentes no carregamento Flash que você espera do carregamento do navegador regular. Depois de executar um packet sniffer, a única diferença real que eu posso ver é que o tipo de conteúdo é diferente.
Os usos modelo attachment_fu, andlooks como este:
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
Então, como posso corrigir o tipo de conteúdo que o Flash envia? E, por que attachment_fu confiança o tipo de conteúdo enviado pelo navegador, em vez de determiná-lo por conta própria, usando números mágicos ou algo assim?
Tenho notado que se eu remover o :content_type => :image
ou o validates_as_attachment
, ou se eu mudar o controlador para save(false)
chamada, o objeto é criado, mas attachment_fu não fazer o seu trabalho de redimensionamento da imagem.
Solução
Infelizmente, os envios Flash são sempre transmitidos com o tipo de conteúdo "application / octet-stream". Provavelmente, a solução mais fácil seria usar mimetype_fu adivinhar as mimetype em um callback before_validation . Paperclip tem essa funcionalidade incorporada.
Outra opção é substituir is_image? usar seu processador de imagem para determinar realmente se o arquivo é uma imagem (em rmagick por exemplo, você pode abri-lo e ver se ele tem todas as camadas). Esta é definitivamente uma solução mais intensivo de recursos, mas ele garante que você aceita todos os arquivos que você pode processar e não outros.