"406 Not Acceptable" for file upload in RoR with AJAX - ruby-on-rails

Tis is my view:
<%= form_for item, :url => comment_item_path(item), :html => {:remote => true, 'portal-transform' => true, :multipart => true} do |f| -%>
<%= f.fields_for :updates, Update.new, :index => nil do |m| -%>
<%= m.text_area :comment %><br />
<%= m.file_field :attachment %>
<% end -%>
<%= f.submit "Comment" %>
<% end -%>
And controller action:
respond_to do |format|
format.js do
render :json => {}
end
end
When I submit the form with only comment (text_area) field entered and keep attachment (file_field) field blank, it render exactly what expected.
But when I submit the form with attachment, it resulted in:
Completed 406 Not Acceptable in 56ms
What went wrong for me? Please guide.
Thanks.

Browsers do not allow file uploads via AJAX for security reasons. If you leave the form's file_field blank however, the form submits normally with no error, which explains the behaviour you are seeing.
To upload files via AJAX in Rails 3, you can use the Remotipart gem.
http://os.alfajango.com/remotipart/
Here is an example usage:
http://thechangelog.com/post/7576700785/remotipart-rails-3-ajax-file-uploads-made-easy

Related

Rails unknown format on AJAX

I'm trying to implement a very simple file form using the remotipart gem. Most of my files are the exact same as the tutorial ones:
timeline.html.erb :
<%= form_tag new_feed_path(:format => "js"), remote: true, :html => { :multipart => true } do |f| %>
<%= hidden_field_tag :brief_id, #brief.id %>
<%= file_field_tag :file %>
<%= submit_tag "Send", class: "btn btn-success" %>
<% end %>
briefs_controller.rb
def new_feed
puts params
respond_to do |format|
format.js
end
end
new_feed.js.erb
alert('success!');
<% if remotipart_submitted? %>
alert('submitted via remotipart')
<% else %>
alert('submitted via native jquery-ujs')
<% end %>
But everytime I submit the form, I get the following error in the logs:
Processing by ResourcesController#create as HTML
Completed 406 Not Acceptable in 14ms
ActionController::UnknownFormat - ActionController::UnknownFormat:
Did I miss something ? I know ajax file upload can be tricky on RoR, but remotipart seems to be a viable solution.
EDIT I managed to fix the first issue by adding :format => "js" , but now I face another problem: none of the form datas are sent. In fact, here are the sent params:
{"controller"=>"briefs", "action"=>"new_feed"}
Check out the example from Remotipart's docs.
Looks like you're not passing :html => { :multipart => true } to form_for
try it
<%= form_tag new_feed_path, html: {multipart: true }, method: :post, remote:true do |f| %>
<%= hidden_field_tag :brief_id, #brief.id %>
<%= file_field_tag :file %>
<%= submit_tag "Send", class: "btn btn-success" %>
<% end %>
edit
try it
install this gem pry
RailsCast Pry
briefs_controller.rb
def new_feed
binding.pry #just to be sure that this action is not called
puts params
respond_to do |format|
format.js { render 'new_feed') # modify this
end
end

redirect from new action to create action with params

Im trying to design a shopping cart. i.e a customer shopping online adds a product to their trolley.
I want to go straight to create action from my new action without going to new.html.erb with pre-set values in my params
Here is what I have so far:
#trolley_id += 1
redirect_to :controller => 'trolleys', :action => 'create', :id => #trolley_id, :something => 'else', method: :post
This redirects me to my index action
To do this with javascript templates, it would look like this:
view
= form_form Trolley.new, remote: true do
-# form goes here
The remote true will submit it as javascript, which will try to render a javascript template.
Your create action can either render :create or let Rails render your template automatically. Since it came in as a javascript request, Rails will render the template with format js.
trolleys/create.js.erb
var html = "<%= j render 'trolley_row', trolley: #trolley %>
$('table.trolleys body').append(html);
I managed to resolve my problem. I created a form in my Product_controller#show that will go straight to my Trolley_controller#create and create an entry in my Trolleys table
<%= simple_form_for [#product, #trolley] do |f| %>
<%= f.input :quantity, collection: 1..12, prompt: "select quantity" %>
<%= f.input :product_id, :as => :hidden %>
<%= f.input :user_id, :as => :hidden %>
<%= f.button :submit, "Add to Basket" %>
<% end %>

Why does this select field appear multiple times in my Rails form?

I've got a Rails application that is using nested forms. Details follow and I tried this solution (Rails 3 Nested Models unknown attribute Error), but for some reason, the field is repeating multiple times instead of listing and saving the options correctly. Thanks in advance for your help!
Model information for Newsavedmaps
has_many :waypoints, :dependent => :destroy
accepts_nested_attributes_for :waypoints
Newsavedmap_controller
def new
#newsavedmap = Newsavedmap.new
waypoint = #newsavedmap.waypoints.build
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #newsavedmap }
end
end
def edit
#newsavedmap = Newsavedmap.find(params[:id])
if #newsavedmap.itinerary.user_id == current_user.id
respond_to do |format|
format.html # edit.html.erb
format.xml { render :xml => #activity }
end
else
redirect_to '/'
end
end
Maptry View
<% form_for #newsavedmap, :html=>{:id=>'createaMap'} do |f| %>
<%= f.error_messages %>
<% f.fields_for :waypoint do |w| %>
<%= w.select :waypointaddress, options_for_select(Waypoint.find(:all, :conditions => {:newsavedmap_id => params[:newsavedmap_id]}).collect {|wp| [wp.waypointaddress, wp.waypointaddress] }), {:include_blank => true}, {:multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints"} %>
<% end %>
<% end %>
When I use the above code, my form works correctly, but submitting it gives me this error:
UnknownAttributeError (unknown attribute: waypoint)
When I change ":waypoint do |w|" to ":waypoints do |w|" in the view, the select field disappears when the user is creating a new record, and in the edit view, the select field appears several times (however many waypoints the user saved in the record.)
How can I get this form field to work properly?
EDIT 1
Here is my latest attempt. For new records, the select field does not appear. However, in the edit view, the select field appears multiple times. This is a Rails 2 application, FYI. Taking a cue from the comments, I used a collection_select approach (not collection_for_select because I couldn't find documentation for that.) Again, I appreciate your help!
<% f.fields_for :waypoints do |w| %>
<%= w.collection_select( :waypointaddress, #newsavedmap.waypoints, :waypointaddress, :waypointaddress, {:include_blank => true}, {:id =>"waypoints"} ) %>
<% end %>
Your form has the following problems.
Use f.fields_for :waypoints since the argument needs to match the name of the association.
Use collection_select rather than select, since you have an ActiveRecord model behind that field.
So, taking that into account, you could try this for your form:
<% form_for #newsavedmap, :html => { :id => 'createaMap' } do |f| %>
<%= f.error_messages %>
<% f.fields_for :waypoints do |w| %>
<%= w.collection_for_select :waypoint, :waypointaddress, #newsavedmap.waypoints, :waypointaddress, :waypointaddress, { :include_blank => true }, { :multiple => true, :class => "mobile-waypoints-remove", :id =>"waypoints" } %>
<% end %>
<% end %>
The API for collection_select is a bit tricky to get right. I usually need a few attempts as well. This previous SO question may help clear things up: Can someone explain collection_select to me in clear, simple terms?

Rails / Paperclip: file_field not displaying

I'm attempting to use PaperClip and have been following the quick start found on their GitHub page.
I've got the gem install, model & controller set up, and in the view I have:
<% form_for #account, :html => { :multipart => true } do |f| %>
<%= f.file_field :image %>
<% end %>
But nothing displays when the page renders. I've stripped out all CSS to ensure that isn't an issue, but still not luck. Any thoughts on why the file picker isn't displaying? Thanks.
Not sure what version of Rails you are using but I think you forgot the equals sign in the form helper, try:
<%= form_for #account, :html => { :multipart => true } do |f| %>
<%= f.file_field :image %>
<% end %>

Problem using 'responds_to_parent' with an iframe and AJAX to upload a file

I followed instructions from the "AJAX file uploads in Rails using attachment_fu and responds_to_parent" article. In my case I am using Ruby on Rails 3 and Paperclip.
What I made is the following:
I have installed the 'respons_to_parent' plugin running this command in the Terminal:
rails plugin install git://github.com/itkin/respond_to_parent.git
After installing, I restart Apache.
In my view I have:
<%= form_for(#user, :html => { :multipart => true, :target => 'upload_frame' }) do |f| %>
<%= f.file_field :avatar %>
<%= f.submit "Submit" %>
<% end %>
<div id="test">Here is a test</div>
<div id="stuff">Here is some stuff</div>
<iframe id='upload_frame' name="upload_frame" style="width:1px;height:1px;border:0px" ></iframe>
In my controller I have
def action
respond_to do |format|
...
format.js {
responds_to_parent do
render :update do |page|
page.replace_html :test, "This is the resulting test"
page << "alert($('stuff').innerHTML)"
end
end
end
end
end
Trying to submit the form, all about the file uploading works (Paperclip handle correclty files, ...) and in the log file there aren't errors.
The only thing that isn't working is the AJAX part. In the example
page.replace_html :test, "This is the resulting test"
page << "alert($('stuff').innerHTML)"
don't update the page (BTW: where these should have effect? in the "main view" or in the "iframe view"?). It doesn't work also if I try to delete the 'respons_to_parent' statement or if I put them in the 'action.js.rjs' file.
Where I am wrong?
SOLVED
I had forgotten to add :url => users_account_path +. "js". So the view become:
<%= form_for(#user, :url => users_account_path +. "js", :html => { :multipart => true, :target => 'upload_frame' }) do |f| %>

Resources