I am available for freelance work! Click here to email me.

SWFUpload, Paperclip and Ruby on Rails

May 15th, 2008

Edit: Added paperclip validations to photo model. Fixed a bug with the js (thanks to Kevin). Commented the js file and added all methods used by SWFUPload.

SWFUpload

SWFUpload is a small JavaScript/Flash library to get the best of both worlds. It features the great upload capabilities of Flash and the accessibility and ease of HTML/CSS.

SWFUpload is a brilliant tool built with flash and javascript that allows you to upload multiple files at the same time, allows you to display progress bars and various other useful things. The front end is left wide open by the SWFUpload API so it gives you complete control over how the UI works.

Paperclip

As many of you might have realised, I love Paperclip. It’s a great plugin that takes care of all the grunt work and lets you get on with other stuff. I’ve covered how to use Paperclip before.

Making Rails Play Nice with SWFUpload

There are a couple of pitfalls when using SWFUpload with your projects. I’ve covered them below:

Scrambled Mime Types

This is an annoying problem caused by the upload facility in Flash. It basically means that all the files you upload via SWFUpload have the content type of application/octet-stream, which in most cases isn’t what you want.

To fix this you will want to use the Mime-Types gem. To Install, simply do the following:

gem install mime-types

Now that you’ve got the mime types gem installed remember to require it somewhere in your code:

require 'mime/types'

The way I’ve used it in the test project at the bottom is instead of assigning files to a model via @photo.file = params[:photo][:file], I’ve created a custom method that fixes the mime type then passes the file to the correct method.

# Fix the mime types. Make sure to require the mime-types gem
def swfupload_file=(data)
  data.content_type = MIME::Types.type_for(data.original_filename).to_s
  self.file = data
end

This takes care of the first problem.

Problems with Sessions

Flash has problems dealing with Rails sessions so a couple of quick fixes are needed. The first is to hack the sessions class. The fix can be found here.

I’ve included that code into a file called swfupload_fix.rb and placed it inside my initializers folder, so it’s loaded by the app is started.

Next add the following to your controller that handles the uploads:

session :cookie_only => false, :only => :create
The Controller

By default, SWFUpload passes the post variable of Filedata when uploading. This can be changed easily if needed. The way I’ve dealt with the uploading in the test application is as follows:

def create
  # SWFUpload file
  if params[:Filedata]
    @photo = Photo.new(:swfupload_file => params[:Filedata])
    if @photo.save
      render :partial => 'photo', :object => @photo
    else
      render :text => "error"
    end
  else
    # Standard upload
    @photo = Photo.new params[:photo]
    if @photo.save
      flash[:notice] = 'Your photo has been uploaded!'
      redirect_to photos_path
    else
      render :action => :new
    end
  end
end

There’s probably a better way to do it, but for an example it shows you to logics of everything.

Linux and Flash Upload Progress

As Tim mentions in the comments there is a problem with displaying upload progress in Flash for Linux. It is covered around the net and alos mentioned in the documentation for SWFUpload:

The uploadProgress event is fired periodically by the Flash Control. This event is useful for providing UI updates on the page.

Note: The Linux Flash Player fires a single uploadProgress event after the entire file has been uploaded. This is a bug in the Linux Flash Player that we cannot work around.

So basically it’s boned on linux and there’s nothing you can do about it.

SWFUpload and Paperclip App

Hopefully, this should get you on your way to using SWFUpload with Paperclip in Rails. However, I’ve created a small app that should help you on your way to getting things working. If you have any problems or find any thing that could be done better, let me know and I’ll fix them up.

It has been tested on Firefox 2.0, Safari 3.1.1 and IE 7 on Windoze Vista. Not tested on IE 6 because, quite frankly, it can fuck right off.

To try the app: unzip the file, change to the swfupload directory then run the following:

rake db:migrate
ruby script/server

Then you should be able to see it by visiting http://localhost:3000.

SWFUpload Test Project

A test project to show how to get Ruby on Rails, SWFUpload and Paperclip to play together nicely.

You can also grab the example application from github:

git://github.com/JimNeath/swfupload---paperclip-example-app.git

Credit Where Credits Due

A lot of places helped be get my head around this stuff. So A massive thanks to Andy Stewart over at Air Blade Software and Dylan Vaughn.

More Resources

(Possibly) Related Posts

Recommend Me

If you found this post or anything else on this site of any use, then please take the time to recommend me on Working with Rails.

You can follow any responses to this entry through the RSS 2.0 feed. Trackback from your own site.

  • joemsak
    For anyone having the InvalidAuthenticityToken error, check out this comment from my blog post that followed this article:

    http://www.joesak.com/2009/09/18/online-photo-gallery-payment-order-fulfillment-ruby-on-rails-tutorial/
    (@vincent's comment at the bottom)

    QUOTE:
    Thank you for the instructions. For Rails 2.3.5, you should delete both of the following lines in your photo or asset controller:
    #session :cookie_only => false, :only => :create
    #skip_before_filter :verify_authenticity_token, :only => ['create', 'destroy']
    Instead, follow the example below to make SWFUpload work with Rails session, i.e. to avoid the InvalidAuthenticityToken error: http://github.com/lardawge/swfupload-rails-authentication/tree/paperclip-example.
    When you follow the example above, pay attention to the following:
    1. Changes in the javascript in the photo views.
    2. Changes in session_store.rb and environment.rb to refer to the app/middleware folder, which you should copy from the example.
    Good luck and have fun.
  • tscolari
    Hello,
    I tried as your said, but Im getting 302 error because my controller is redirecting me for the login page.
    I've placed your initializer and the session line on the controller.
    Im usiging authlogic, any idea where i could look for a fix?
  • An old post but still useful and comes up near the top on google for rails swfupload,

    But if you'd replace
    MIME::Types.type_for(data.original_filename).to_s
    with
    MIME::Types.type_for(data.original_filename).first.content_type

    You'd save some headaches.
  • Yeah not easy to implement this upload feature. We actually need a kind of "official" way of doing things. Implementing such feature might break in the next release of Rails don't you think?
  • lardawge
    Hi Jim,

    Thought I would let you know I created a branch here: http://tiny.cc/swfuploadrailsauthentication using paperclip. So there is an example with both attachment_fu and paperclip now. Only made sense because I actually use paperclip in my own projects.

    ~Larry
  • vincent_learner
    Thanks Jim and Larry! To help the next
    researcher, I am posting this tip. You should delete both of the following lines in your
    photo or asset controller:

    #session :cookie_only => false, :only => :create
    #skip_before_filter :verify_authenticity_token, :only => ['create',
    'destroy']

    Instead, follow the example below to make SWFUpload work with Rails
    session, i.e. to avoid the InvalidAuthenticityToken error:
    http://github.com/lardawge/swfupload-rails-authentication/tree/paperc....

    When you follow the example above, pay attention to the following:

    1. Changes in the javascript in the photo views.
    2. Changes in session_store.rb and environment.rb to refer to the app/
    middleware folder, which you should copy from the example.

    Good luck and have fun.
  • GreenAsJade
    I did

    git clone git://github.com/JimNeath/swfupload---paperclip-example-app.git
    cd swfupload---paperclip-example-app

    rake db:migrate

    and get

    rake aborted!
    undefined method `cache_template_extensions=' for ActionView::Base:Class

    My RAILS_GEM_VERSION is 2.2.2

    Is there an easy way to get past this?
  • Sohel Merchant
    Hi, I have been trying to battle with using the demo app with Rails 2.3 with no success yet. My question is that whether using CGI::Session is still feasible with Rails 2.3. After using the application in 2.3 I have found that my files do not get uploaded at all. I am looking for solution which uses CGi Session instead of Rack,
  • I am having the same problem as @peter. I get the "browse" button bug. Nothing happens when I click it.
  • pimpmaster
    +1 vote for Rails 2.3 article
  • Peter
    Dear Jim,
    I downloaded the demo, and got it up and running. I am experiencing a bug though, when I click the browse button nothing is happening. What am I missing here.

    OS: OS X 10.5.6
    Browser: FF 3.0.7

    I get no errors in Firebug console, so I am lost here.

    Any assitance is welcome
  • @Daniel Mattes - I found that a few days a go as well. Using it in a new project and it works well.

    I'm going to redo this article along with a new sample app over the next week I think.
  • lardawge
    I have forked and updated a sample rails app that uses attachment_fu and swfupload to work with rails 2.3 and rack. http://tiny.cc/swfuploadrailsauthentication - All credit goes to cameronyule for the original project and Rob Anderton for creating a solution to work with rails 2.3.
  • John
    Great article.

    I've downloaded the app and tested it. I am using rails 2.2.2
    Even though the upload functionality works (files get uploaded and saved) I noticed in my log I keep getting:

    ActionController::RoutingError (No route matches "/undefined" with {:method=>:get}):

    As I wove this example code into my app, I get the same error message in my log file.

    Plus, when I try to render some rjs to render a partial on the page from the create action after the upload is saved, it keeps trying to make calls back
    to Application Controller ...

    Processing ApplicationController#index (for 127.0.0.1 at 2009-03-17 21:13:47) [GET]

    and the partial that has links to images in the images folder are now all prefixed with gobble-d-gook...

    Processing ApplicationController#index (for 127.0.0.1 at 2009-03-17 21:14:06) [GET]
    Parameters: {"1237328002\\\\\\\""=>nil}


    ActionController::RoutingError (No route matches "/%5C%5C%5C%22/images/icon-pdf.png" with {:method=>:get}):
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/routing/recognition_optimisation.rb:66:in `recognize_path'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/routing/route_set.rb:386:in `recognize'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:182:in `handle_request'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:110:in `dispatch_unlocked'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:123:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:122:in `synchronize'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:122:in `dispatch'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:132:in `dispatch_cgi'
    /usr/local/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/dispatcher.rb:39:in `dispatch'


    Any clues here?

    Is there some special routing this is needed?

    Is there something in rails 2.2.2 that is breaking your example app routes?

    Have you tried this in rails 2.2.2 ?

    Do you get that initial Routing error when the swfobject initializes?

    Thanks in advance.
  • joelm
    vince- The problem was authentication/session management. If you look in the rails log I think you'll see an invalid session error. I'm currently adding
    skip_before_filter :verify_authenticity_token, :only => :create
    in my controller. I don't think this is required, but I haven't gone back to test. I'll try to retract my steps (I meant to write this up here a while ago) to document a complete solution.
  • joelm - I'm seeing HTTP_STATUS of 422 also. I think I've traced it to rails 2.2. The error goes away when you switch your rails app to 2.1. Anyone know of a fix for rails 2.2?
  • lardawge
    Two questions... 1. Is there way to pass sessions with rails 2.3 since it now uses rack instead of CGI? What are the changes needed for that... 2. Can you pass the thumbnailing/processing to a background task (workling/starling) so that swfupload doesn't have to wait for a response while this is happening?
  • gugu
    Hi Jim,

    Thanks to your blog post and your code example,

    I 'm discoverd paperclip in my project group member.

    Now. I have a new project.

    Making Image Gallery through paperclip and swfupload.

    Model structure as follow.


    Album has_many :photos,
    ----------------------------------------------------------------------------------------------------
    photo belongs_to :album
    has_attached_file :image,
    :styles => {:thumb=> "90x55", :tiny => "50x50>" }
    ----------------------------------------------------------------------------------------------------
    I don't know How resolve this issues.

    help me! experienced person.
  • Mike
    I have it working in rails 2.2.0 but with one problem.
    When trying to set a style that just makes sure the image is under 800 wide {:scaled => "800>"}

    i get an error saying that the width could not be found.
    (You have a nil object when you didn't expect it!
    The error occurred while evaluating nil.width):

    Is there anyway around this because everything else works fine.

    Thanks for the work guys you are amazing.

    Mike.
  • joelm
    I sincerely appreciate your efforts on this so far and getting it working again. I'd hate to have to degenerate to one of the 'keep polling the server' solutions if we can't fix this. So, if you need any help with testing, I'd be glad to help! (I don't know that I'm able to resolve the issues, else I'd have done so already!)
  • For all those having troubles with Flash 10 (which is what breaks the current version), I shall have a play around and update the test app and the article with all the details you need :)
  • joelm
    jts- The (partial) solution is to update to swfupload 2.2.0 (http://code.google.com/p/swfupload/downloads/list, it says it's beta 4, but it is really beta 3 as of today.) This update adds a new required parameter 'button_placeholder_id : "upload_holder", where "upload_holder" is the ID of a DOM element that will be REPLACED by the swfupload flash. You can then press THIS button to get a file dialog. Then you use Jim's 'upload' button to start the upload. (The docs with swfupload describe other options for the button.)

    The good news is that this works. The bad news is that that after uploading all the data the upload fails with HTTP_STATUS of 422 which means 'unprocessable entry'. This apparently means the file is the correct type, but is somehow invalid. I'm running on a Mac but I tried this with Safari, Firefox and IE (from a PC). Using mongrel and webrick as servers. I also changed the upload url to '/files' to take paperclip out of the equation. No joy. It still fails.

    Does anyone have any suggestions on what might be causing this new problem?
  • jts
    I gave your example a go, and the browse button failed silently. I was devistated! Turning on debugging gave me this

    SWF DEBUG: Event: fileDialogStart : Browsing files. Multi Select. Allowed file types: *.jpg;
    SWF DEBUG: Exception: Error: Error #2176

    Google told me that error 2176 corresponds to use of your call to
    swfu.selectFiles()
    Specifically, deprecated. Not compatible with Flash Player 10.

    This is em, broken. Any chance of fixing it?!
  • andy
    maybe the problem is that my Windows is on Flash 10 and my Mac & Linux are both Flash 9?
  • andy
    new question

    I've got this mostly working, except when someone is on Windows. Then the HTTP-ACCEPT is "text/*" which returns a 406 error. Adding this as a Mime::Type doesn't work since the server (mongrel) starts returning files for download.

    any else have this issue?
  • I'm the author of FancyUpload. Just wanted to say thanks for that detailed documentation for your installation. I'll definitely link to it in my documentation.

    Too bad that FileReference (the AS3 API that handles the upload) acts (even in Flash 10) so different on Mac and Linux. You always need to add a proper fallback (normal upload form) when you use solutions like SWFUpload or FancyUpload.
  • andy
    has any done this technique with an object having multiple files attached?

    I'm wondering how best to do a new / create considering that swfupload is sending a post for each file selected. Which, if you include form params, would result is multiple objects with one attachment.

    I thinking somehow do a create post for the first uploaded file and updates after that...

    hmm.. any ideas?
  • Hi Jim,

    Thanks to your blog post and your code example, I have been able to get paperclip to correctly find the mime-type of an uploaded file. I use mimetype_fu though.

    I haven't been able to make SWFupload work, but that's not super important for the time being.

    Best regards,
  • satynos
    After installing sample app as stated, I can see the new photos page, but because of some reason when I click the button, nothing is happening. Would appreciate it if somebody could shed the light. I don't see any javascript errors also in firebug.

    My Platform:
    WinXP
    Rails 2.1.1
    Flash 10

    Thanks in advance.
  • Thanks for the help! One thing (and maybe this is obvious) I've noticed is that all the examples deal with uploading the file only, and not with submitting other form data. If I want to use this uploader in a create function, it's likely I'll have other attributes I'll need to set.

    What's the preferred way to pass along the rest of the information?
  • tejo
    ops....some code was ripped of...obviously _swfupload_session and authenticity_token must be filled with rails value:

    u session.session_id
    u form_authenticity_token
  • tejo
    if you want to use this kind of approach to file uploads, and you're using rails 2.1.x and don't want to disable the protect_against_forgery thing you can do this:

    var settings = {
    upload_url: "?_swfupload_session=",
    ......
    ....
    ....
    post_params : {authenticity_token : ''},

    hope this can save your time.
  • Rockey
    Jimm,

    I am getting problem with the function:

    # Fix the mime types. Make sure to require the mime-types gem
    def swfupload_file=(data)
    data.content_type = MIME::Types.type_for(data.original_filename).to_s
    self.file = data
    end
    I have added this function to model class. I have also added two more functions uploaded_data and detect_mimetype there

    def uploaded_data=(file_data)
    return nil if file_data.nil? || file_data.size == 0
    self.content_type = detect_mimetype(file_data)
    self.filename = file_data.original_filename if respond_to?(:filename)
    if file_data.is_a?(StringIO)
    file_data.rewind
    self.temp_data = file_data.read
    else
    self.temp_path = file_data.path
    end
    end

    def detect_mimetype(file_data)
    if file_data.content_type.strip == "application/octet-stream"
    return File.mime_type?(file_data.original_filename)
    else
    return file_data.content_type
    end
    end

    I have already installed mime-types #gem install mime-types. and added statement require 'mime/types' in controller as well as Model.

    when I am trying to assign MIME-Type, I am getting the error "undefined method `content_type=' for #"

    But if I am writing statement this way:
    content_type = MIME::Types.type_for(data.original_filename).to_s
    puts(content_type)

    It prints the actual image type not application/octetstream.

    I also tried this with simple html file tag:
    params[:photo].content_type = File.mime_type?(params[:photo].original_filename)
    This statement is also giving problem:

    "undefined method `content_type=' for #"

    But If I will use this way:
    content_type = File.mime_type?(params[:photo].original_filename)
    Then I am getting the right content_type

    But can be the problem. Please help
  • @Kevin Thanks a bunch! That Safari bug was really driving me insane. Works perfectly with the quoting!
  • nap
    Oh man that was mangled pretty badly... Hopefully this will work:


    upload_url: "?_yourappname_session=&authenticity_token="
  • nap
    oh man that was mangled pretty badly... Maybe this will work (or please correct in moderation):

    upload_url: "\?_yourappname_session=\\&authenticity_token=\"
  • nap
    Anyone using Rails 2.1 may run into the issue that Session IDs are multi-line... In SWFU object setup, if you need to pass the session id by hand, you can specify it like this:

    upload_url: "?_yourapp_session=&authenticity_token="
  • For anyone wanting to get this working quickly on Rails 2.1, a simple fix for the InvalidAuthenticityToken error is to add:

    skip_before_filter :verify_authenticity_token

    to the top of your attachments/photos controller, rather than disabling protect_from_forgery across your whole application.
  • I'm also getting the InvalidAuthenticityToken error. I've tried passing it as a post_param and as part of the URL, but nothing seems to be satisfactory. Anyone have an idea of what's going on there yet?
  • @lardawge: As a quick workaround you could rename the image in a before_save filter and set the new image path to the database as well.
  • Stag
    I too am having trouble with an ActionController::InvalidAuthenticityToken error. The rails project im using this with uses a login and hence has a user_id in the session.

    I found I had to comment out my protect_from_forgery in the application controller to get it to work but that just left me with a "couldnt find user without id" error.

    I like the look of delagoya's solution as im working with post_params already but putting " session_data: ìî " in there didnt accomplish anything for me.

    I also used post_params to put in the authenticity token but got no result with that either.
    For anyone whos interested the token can be got with:
    $('#form-id div input').val()
    replacing form-id with the forms id :P

    Anyways any help would be greatly appreciated.
  • @delagoya - I've not actually tried that. I'll have a play around with it and update the sample app.

    @lardawge - I've not actually tried doing anything like that yet. You may be able to use a Proc but I'm not sure yet. I'll have a look into it and let you know.
  • lardawge
    Jim,
    Couple questions-

    1. Any way to rename the files? Say for example if I had a form with 'first_name' 'last_name'. Is there a way to rename each file 1-first_name.jpeg, 2-first-name.jpeg, ect.

    2. Along the same lines, folder naming/directory. Folder= first_name+last_name?

    I know it may be slightly outside the scope of what you are trying to do here but any tips pointers would be appreciated.
  • OK, stupid question, but why not just use SWFUpload's "post_params" setting? I tried this out in your example app and it seems to work. Basically I:
    1) deleted the swfuplaod_fix.rb file that altered the cgi::session classes,
    2) commented out "session :cookie_only => false, :only => :create" from photos_controller
    3) and added this to the view:

    var settings {
    ...
    post_params: {session_data: "" },
    ...
    }

    And the app seems to work just fine. The post url is kept short, and you can also pass in other params, like user_ids to grab the current user, etc. etc. Testing now on https using restful_auth + cookie session store. Will post results when done.
  • yuri
    Jim, thanks for the great work!
    While it's not possible to protect the upload with before_filter in controller it can be easily done in the view.
    With restful_authentication it's .
    It would be brilliant if anything could be done with protected_from_forgery which doesn't seem to work in Rails 2.1
  • Jim --
    thanks for the brilliant post. It works like a charm.
    I had trouble using this with a sortable list as the id of the uploaded files' div was based of off the flash file id and not the db row id.
    (it would work fine after a page refresh, but who wants that?)
    I came up with this modification to the upload.js file for anyone out there who might be interested:

    upload_success: function(file, data)
    {
    $('#' + file.id).replaceWith($(data));
    }

    This way the html element has the id you pass back from the controller in the partial data instead of SWF_0_x as the element id
  • Wow, man. This works like a charm! Thanks for getting all of this great info out here for the rest of us. I used the cues given from your sample app to get everything up and running in my app with the quickness. Kudos!
  • Ken, you should take a look at a Rails-generated form: you'll see a hidden input-element right after the form-element is opened which contains an authenticity token. What it comes down to is that Rails expects this token to be posted along with every form-post you do to the application. It checks if the token from the form matches the token in application.rb to be sure the form is submitted by your app.

    A solution could be to somehow force the Flash-upload-thingy to include the authenticity token, but I'm not sure how to do this as I haven't tried all this stuff out yet.

    Anyway, I hope you've got a clearer view on what's going awry here.
  • Ken
    By default, with rails 2.1.0, I get this:

    Processing PhotosController#create (for 127.0.0.1 at 2008-06-18 20:31:15) [POST]
    Session ID: be0fd9a1adcc1e75dc97ec4e930a1850
    Parameters: {"Filename"=>"signature.jpg", "action"=>"create", "Upload"=>"Submit Query", "controller"=>"photos", "Filedata"=>#}

    ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
    /opt/local/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/request_forgery_protection.rb:86:in `verify_authenticity_token'
    /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/callbacks.rb:173:in `send'
    /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/callbacks.rb:173:in `evaluate_method'
    /opt/local/lib/ruby/gems/1.8/gems/activesupport-2.1.0/lib/active_support/callbacks.rb:161:in `call'
    /opt/local/lib/ruby/gems/1.8/gems/actionpack-2.1.0/lib/action_controller/filters.rb:430:in `call'
    ...

    I had to comment out the 'protected_from_forgery' command in applications.rb to get this to work.

    I don't understand how session handling works to determine how to make this work with sessions. Ideally, I would like to put image uploads behind a login screen, but unless I can get at the original session, there's no way to do this.

    Hopefully somebody has some suggestions....
  • Michael
    Ok, I now have it working. There was in issue in my "Create" method. One problem though, I can't seem to control the sizes of the image previews during upload (some are ginormous) and all of the previews present as though they're "partials" (although I removed that code). Any ideas?

    Thanks,
    Michael
  • Michael
    I am still getting the Massive Error issue. I don't care for any type of security. How can I simply disable everything so as to just get this working?
  • RubyPimp
    I am trying to take this a step further and get this working with attribute_fu, As an example

    :person has_many :photos, :attributes => true

    Using this awesome plugin allows me to add multiple photos on the fly in form_for :person.

    Where I hit the snafu is the controller code. Since att-fu automatically builds through the association, you actually don't need a controller for Photos at all. As a result I have no idea how to set the params for swfupload_file.

    Any ideas on how I can work around this?
  • deramoo
    Thank you for this great work. But I met a problem with SWFUpload and Rails2 that my session data doesn't seem to be correct. Here is the detail of the problem.

    I am using a two-page upload wizard. In the first page(Page A) you can select a catalog to upload the file, and on the second page(Page B) you select and upload the file itself. I put the catalog id into session after Page A, and get it back in Page B to create an active record. But when I get the ID back from the session, the ID seem like this:

    first time in Page A, I put 1
    first time in Page B, I get nil
    second time in Page A, I put 2
    second time in Page B, I get 1
    third time in Page A, I put 3
    third time in Page B, I get 2
    ... ...

    why this happens? any clues on solving this? Thank you.
  • Rails 2.1 Happy. !

    Add following for your controler

    class PhotosController false, :only => :create
    protect_from_forgery :except => :create
  • @masch - As Tim has pointed out in the comments, there appears to be problems with using flash to upload files with linux.

    @Tim - I'm sick of testing things in IE6. I hate it, as I'm sure most developers/designers do.
  • tim
    "Not tested on IE 6 because, quite frankly, it can fuck right off."

    haha, I totally share that sentiment!
  • masch
    I'am using Fedora 9 with Firefox 3 beta 5.
    Salu2..
  • @masch - Can you let me know what browser/OS you're using?

    @Tim - I've edited the article the point out that it's basically fucked under linux. Thanks for bringing it to my attention.
  • masch
    @Jim
    The only thing i got it's:
    127.0.0.1 - - [16/May/2008:17:40:23 ART] "POST /photos HTTP/1.1" 422 10629
    - -> /photos

    Salu2...
  • Tim
    SWF DEBUG: SWFUpload Init Complete
    SWF DEBUG:
    SWF DEBUG: ----- SWF DEBUG OUTPUT ----
    SWF DEBUG: Build Number: SWFUPLOAD 2.1.0 FP9 2008-05-12
    SWF DEBUG: movieName: SWFUpload_0
    SWF DEBUG: Upload URL: /photos
    SWF DEBUG: File Types String: *.jpg;
    SWF DEBUG: Parsed File Types: jpg,
    SWF DEBUG: File Types Description: Jpg Image Files (*.jpg;)
    SWF DEBUG: File Size Limit: 3221225472 bytes
    SWF DEBUG: File Upload Limit: 0
    SWF DEBUG: File Queue Limit: 0
    SWF DEBUG: Post Params:
    SWF DEBUG: ----- END SWF DEBUG OUTPUT ----
    SWF DEBUG:
    SWF DEBUG: Event: fileDialogStart : Browsing files. Multi Select. Allowed file types: *.jpg;
    SWF DEBUG: Select Handler: Received the files selected from the dialog. Processing the file list...
    SWF DEBUG: Event: fileQueued : File ID: SWFUpload_0_0
    SWF DEBUG: Event: fileDialogComplete : Finished processing selected files. Files selected: 1. Files Queued: 1

    -------------

    There are apparently lots of people who are having issues with flash and ubuntu feisty, so I would chalk it up to that. There is one more line that gets added but the browser crashes before i can capture it. it always happens immediately after i click upload. I am going to give up on this and attribute it to a flakey ubuntu flash implementation (which is apparently well documented). Thankfully I have other computers I can use :)

    Tim
  • @Tim - Odd. Try setting the debug variable in /app/views/photos/index.html.erb to true and see what that spews out. Might be of some use.
  • Tim
    Interestingly enough when I go to the fancyupload URL listed in this thread and try the demo I get similar behavior. So this is likely something that has to do with my flash installation and not your nifty project. sorry for the noise, I will see if I can debug whats going on in my local environment.
  • @Tim - Will look into it today to see if I can get it working. I've have to move it over to Ubuntu I've got running on my PS3 (geek). I'll see what I can do.
  • Tim
    @Jim - I am using firefox on ubuntu. also have the same problem with epiphany. I tried applying Kevin's patch to see if it would make any difference, and it does not. The image simply toggles to uploading, and the progress bar never moves. I do not get an image on the server side, and the file is not uploaded. Outside of that its damn sexy :) I wish I could get it to work for me...
  • @Masch - Check what error messages you're getting from mongrel/webrick. The massive error message is just a sample of how to handle the error handling. It means something has gone on the server side.

    @Nate Leavitt - It should work with ImageMagick. What problems are you having?

    @Kevin - Thanks for the fix. I'll update the source. Still not had change to test on my mac yet, but will get issues sorted when I get chance.

    @omarvelous - You should just be able to select your images with the browse button and then upload with the upload button. I did it this way so people could see how the browse/upload buttons could work.

    I'll add fixes and look into the other issues today. It was just a quick example I knocked up yesterday to show to do uploads with paperclip/swfupload.

    Would anyone be interested in me putting this up on github so people can add their own patches?
  • omarvelous
    Whoops.... I take that back... I see I had to press the button once more.... I wonder if that could be changed? Change it to automatically begin uploading as soon as they are selected.
  • omarvelous
    I too am experience freezing with the multi upload feature. Using XP, and FF 2...

    Will try with IE and Safari soon.
  • omarvelous
    I was just on your website yesturday, after googling to find a solution to integrate SWF and Paperclip.... I see I was only a day late! Ur the man!! Bookmarked!
  • oops that line got mangled..
  • The fix seems to be to quote the word 'class' in line 16 or upload.js,

    div = $('').attr({ id: file.id,'class': 'photo'});

    now works in Safari on OSX.
  • Good write up. Bizarrely (given your comment), I can only get the example to run in FF (3.0 b5) under OSX. Safari gives the following errors..

    SyntaxError: Parse error
    http://localhost:3000/javascripts/upload.js?1210847188 (line 16)

    Can't find variable: Upload http://localhost:3000/ (line 76)
  • Doesn't work in Safari on Mac.

    Works fine in Firefox.
  • Nate Leavitt
    Hi Jim,

    Thanks for the article! I am having some issues with the thumbnails being created. I have ImageMagik installed... hmm.
  • masch
    Hi! Tim
    I downloaded and run the test, but when i try to upload a file in java script mode i got this error:
    MASSIVE ERROR!!!1
    Do you know how to fixed?

    Salu2...
  • @coxy - I've never actually used FancyUpload. It used flash (from what I've read) so I assume the same problems (and solutions) will apply.

    @Tim - Is it just the progress bar that doesn't move? Does the image replace the content of the div with the details in? I've got a feeling that it's something to do with the way I've implemented the progress code. Are you running OS X and FF? Because that's what I've had problems on before.
  • Tim
    Hi Jim,

    Downloaded your sample project, installed the gem, ran the migration, and I am able to upload a file normally, but the swfupload always just hangs. no errors in server log, no messages anywhere. it shows the image, and and " uploading...", but the progress bar never moves. Upload normally on the other hand works just fine. Any ideas what might be missing?
  • coxy
    Thanks... just what I've been looking for.

    Just wondering how this fairs against FancyUpload (http://digitarald.de/project/fancyupload/) in terms of ease-of-use.. ever used it?
blog comments powered by Disqus
Purify - Issue Tracker

Jim Neath is a 26 year old Freelance Ruby on Rails developer from Manchester, UK.

Recommend Me

Categories