Note: actually there’s one or two steps missing here: you also need the formSubmit function in hobo-jquery. If you have questions, ping me on the list. Even better, this is built into Hobo 1.4.
With the paperclip plugin installed, Hobo supports file uploads, but does not support Ajax file uploads. It seems like it should work, but the file doesn’t get uploaded. The problem is that browsers do not allow Javascript access to the local file system as a security measure.
To get around this, most sites either use a Flash plugin or use an ugly IFrame hack. We’ll use the JQuery form plugin, which packages up the IFrame hack.
You’ll also need this enhancement to Hobo. You can either install the patch, or use 1.1.0.pre3 or 1.3.0.pre26 (?).
The first step is to install JQuery form plugin, using something like this:
<extend tag="page">
<old-page merge>
<custom-scripts:>
<hjq-assets/>
<javascript name="jquery.form.js"/>
</custom-scripts:>
<old-page/>
</extend>
This assumes you’re using the hobo-jquery plugin. See its instructions for more details.
On our application, we have a package that has-many uploads.
class Package < ActiveRecord::Base
hobo_model
has_many :uploads, :dependent => :destroy
end
class Upload < ActiveRecord::Base
hobo_model
fields do
name :string
timestamps
end
has_attached_file :attachment
belongs_to :owner, :class_name => "User", :creator => true
end
Our view is pretty standard Hobo Ajax:
<edit-page>
<after-form:>
<hr/>
<h3>Attachments</h3>
<div part="attachments-div">
<error-messages/>
<table-plus:uploads fields="name, attachment_file_name, attachment_file_size"/>
</div>
<h3>Add an Attachment</h3>
<form with="&new_for_current_user(this.uploads)" owner="package" message="Uploading..." update="attachments-div" without-cancel>
<field-list: skip="package"/>
</form>
</after-form:>
</edit-page>
But we need some extra stuff in the controller to correspond to the requirements listed here for the jQuery form plugin.
class UploadsController < ApplicationController
hobo_model_controller
auto_actions :all, :except => [:index]
auto_actions_for :package, [:create, :new]
def create_for_package
hobo_create_for :package do
if valid?
# we have to ignore the requested file type because the workarounds
# necessary to send files via ajax don't allow us to set the
# headers. So we just assume that we need to send an Ajax
# response. We'll also Wrap that response in a textarea so
# the browser keeps its hands off of it.
ajax_update_response(params[:page_path], params[:render].values, {}, {:preamble => "<textarea>\nvar _update = Hobo.updateElement;", :postamble => "</textarea>"})
else
render(:status => 500,
:js => "alert(\"#{this.errors.full_messages.join(". ").gsub('\n', '')}\");")
end
end
end
endUser contributed notes
-
On December 28, 2011 JezChatfield said:
<include src="rapid" gem="hobo"/> <include src="taglibs/auto/rapid/cards"/> <include src="taglibs/auto/rapid/pages"/> <include src="taglibs/auto/rapid/forms"/> <include gem="hobo-jquery" /> <include src="paperclip" plugin="paperclip_with_hobo"/> -
On December 28, 2011 JezChatfield said:
Without this, I got error messages about "form__for_(Class)" missing error messages.

On December 28, 2011 JezChatfield said:
I found that I had to add more to application.dryml to make this work, without complaint. I added: