In Rails how do I handle multiple, polymorphic file uploads with jquery-file-upload and CarrierWave?
In my project I currently have different models (Project, Message, etc) that:
has_many :assets, :as => :attachable, :depen开发者_JAVA百科dent => :destroy
Each Asset is basically a model with a CarrierWave file. Normally I would just use accepted_nested_attributes on the parent model (Project, Message, etc) and have the file upload fields listed in a fields_for block.
My problem is that since I'm using jQuery-File-Uploader with AJAX the parent model's form will call the parent model's Create method when ever a file is uploaded. The rest of the parent model fields might not be filled out yet. I'm thinking maybe I could have the file uploader call the create method in the Assets controller, but then I would some how have to send the parent model's class so the polymorphic association is stored correctly.
Any ideas of how I might get this working cleanly? Thanks for looking.
OK.
Step 1
add gem 'carrier wave'
to you Gemfile
Step 2
save the code to /lib/flash_session_cookie_middleware.rb
require 'rack/utils'
class FlashSessionCookieMiddleware
def initialize(app, session_key = '_session_id')
@app = app
@session_key = session_key
end
def call(env)
if env['HTTP_USER_AGENT'] =~ /^(Adobe|Shockwave) Flash/
req = Rack::Request.new(env)
env['HTTP_COOKIE'] = [ @session_key,
req.params[@session_key] ].join('=').freeze unless req.params[@session_key].nil?
env['HTTP_ACCEPT'] = "#{req.params['_http_accept']}".freeze unless req.params['_http_accept'].nil?
end
@app.call(env)
end
end
Step3
edit session_store.rb
add the code to the end of file
Rails.application.config.middleware.insert_before(
ActionDispatch::Session::CookieStore,
FlashSessionCookieMiddleware,
Rails.application.config.session_options[:key]
)
Step4
Download jquery.uploadify.js from Uploadify and unzip it.
Step5
- Copy
jquery.uploadify.v2.1.4.min.js
&swfobject.js
to/app/assets/javascripts
if you use Rails3.1 or later, to/public/javascripts
if you use Rails 3.0 or before version. - Copy
uploadify.swf
andcancel.png
to/app/assets/images/
or/public/images
- Copy
uploadify.css
to/app/assets/stylesheets/
or/public/stylesheets
Step6
Edit your application.js, insert below code to it
//= require swfobject
//= require jquery.uploadify
Step7
In you upload page, add this
<input id="uploadify" name="uploadify" type="file" />
Step8
add this code to you upload page
$(document).ready(function() {
<% key = Rails.application.config.session_options[:key] %>
var uploadify_script_data = {};
var csrf_param = $('meta[name=csrf-param]').attr('content');
var csrf_token = $('meta[name=csrf-token]').attr('content');
uploadify_script_data[csrf_param] = encodeURI(encodeURIComponent(csrf_token));
uploadify_script_data['<%= key %>'] = '<%= cookies[key] %>';
$('#uploadify').uploadify({
uploader : '/assets/uploadify.swf',
script : '/photos',
cancelImg : '/images/cancel.png',
auto : true,
multi : true,
removeCompleted : true,
scriptData : uploadify_script_data,
onComplete : function(event, ID, fileObj, doc, data) {
}
});
});
Step9
Write your controller like this
def create
@photo = Photo.new(:image => params[:Filedata])
@photo.save
end
精彩评论