Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 - nested model - has_many - jquery file upload

I have a Post model which has_many :photos. While User creating a new post, user should be also able to select photos for given post.

I am using RAILS 3.2.9, nested_form, carrierwave and jquery-fileupload-rails gem and ryan bates railscasts as a guide.

All seems to be set up correctly, but problem is, when User choose a photo (a fileupload() function is triggered), new Post and new Photo record are created. Once I press "create post" another post record is again created.

Any help/idea is appreciated.

Thank you very much.

Petr

class Post < ActiveRecord::Base
  has_many :photos, as: :attachable, :dependent => :destroy
  accepts_nested_attributes_for :photos, :allow_destroy => true
end

class Photo < ActiveRecord::Base
  belongs_to :attachable, polymorphic: true
  attr_accessible :image, :description, :post_id, :attachable_id, :attachable_type
  mount_uploader :image, PhotoUploader
end


# Post Controller
def create
  @post = Post.new(params[:post])
  @post.save
end


# _form.html.erb
<%= nested_form_for @post, :html => { :multipart => true } do |f| %>
  <%= f.fields_for :photos do |photo| %>
    <% if photo.object.new_record? %>
      <%= photo.file_field :image, id: "fileupload" %>
      <%= photo.hidden_field :id %>
      <%= photo.hidden_field :attachable_id %>
      <%= photo.hidden_field :attachable_type %>
    <% else %>
      <%= image_tag(photo.object.image.url(:thumb)) %>
      <%= photo.check_box :_destroy %>
    <% end %>
  <% end %>
<% end %>

#application.js
$('#fileupload').fileupload();
like image 970
praethorian Avatar asked Jan 25 '13 20:01

praethorian


1 Answers

https://github.com/blueimp/jQuery-File-Upload/blob/master/js/jquery.fileupload.js#L140

The file upload plugin submits the form via Ajax (creating the post) as soon as you select the file (see linked file for source). This will create your objects as soon as they select it.

Why do you need the fileupload plugin? You don't need to submit them via AJAX, so just nested form should be able to solve your problems. Just use link_to_add and link_to_remove with a regular filefield.

EDIT:

Assuming you want to keep the file field plugin (which it seems you do), then you need to have a way of recieving them.

The best way to do this, is inside the posts view page, have the file upload code nested inside a form for your Photos, not inside a nested form for your Post. This way, every photo will post to a photo-create option, and then you can provide a javascript call-back in the photos controller that updates the Post form with a hidden field, telling it which photo_ids were uploaded to this post(and obviously secure this!).

I personally don't like this approach, because you will be uploading and accepting the files before the user creates the post form (meaning they can just navigate away and leave you with 5-10 photos on your server not tied to any post)...but it is a necessary pre-condition if you want them to be able to upload the photos using the AJAX (aka, file upload plugin).

There isn't a super nice way of doing this, file upload work is usually messy. I don't know of any jQuery plugins that work on a file field and allow you to convert a multiple file-field input set into hidden fields containing each individual file.

like image 197
Joe Pym Avatar answered Oct 15 '22 17:10

Joe Pym