5

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();
2
  • What is the source of your file_upload function? That's probably your problem... Commented Jan 30, 2013 at 21:01
  • I am using jquery-fileupload-rails gem (github.com/blueimp/jQuery-File-Upload). Commented Jan 31, 2013 at 19:40

1 Answer 1

5
+100

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your suggestions, but as far as I understood it right. User would have to select image one by one. By using the jquery-file-upload plugin is user able to upload multiple images. Did I understand you correctly? Thanks,
Well, how do you want it to work? When you use the jquery-file-upload, every click it will submit an ajax request to create the element to your server. This is a fine way of going about it...but it requires the parent to be created first, and have a separate controller action to create the form. You can't use both Nested Form and file-upload. They are two different ways of attempting to solve the same problem...
>>"but it requires the parent to be created first" Yeah exactly. I thought that there could be a way how to solve it.
And edited :). Let me know if that helps! If not, we can discuss it more in the Ruby on Rails chatroom?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.