uploading multiple files with attachment_fu
i was recently sharing with someone how to make multiple uploads work with the attachment_fu plugin. as an aside, attachment_fu is the successor to acts_as_attachment. if you were planning to use acts_as_attachment, upgrade your plans and use attachment_fu instead.
multiple file uploads are actually fairly straight forward.
first, in the view:
1<%= file_field_tag 'attachment_data[]' %>
put as many of these in the view as desired. it’s also easy to cause an arbitrary number of them to be added via javascript by the user’s browser.
then, in the controller:
1@attachment = Attachment.new
2params[:attachment_data] ||= []
3params[:attachment_data].each do |file|
4 @attachment = Attachment.create({:uploaded_data => file}) unless file == ""
5end
Attachment is my model for uploaded file—substitute as appropriate. as this isn’t a complete how-to for attachment_fu, i won’t get into configuring attachment_fu or the model here.
that’s it. that wasn’t so painful, eh?
tags: attachment_fu, plugins, ruby, rails
thanks,
but,
what do you put on the show.html.erb?
im lost there
thanks
just this:
<%= file_field_tag 'attachment_data[]' %>
if you want to allow three uploads, put it in there three times. you could even use ajax to allow the user to add it an arbitrary number of times.
the trick lies in the “[]” at the end of “attachment_data[]” which causes the upload data to be submitted as an array of files. the underlying code handles that array, whether it has one file in it or ten.
Thanks a bunch! This helped me out loads.
so how exactly have you done this? I’m guessing you have an attachments table of some kind? if so could you give me some idea of how the table should look?
yes, as i noted in the article above, “Attachment is my model for uploaded file.” it just needs to be a standard attachment_fu compatible model. maybe something like this (untested):
1create_table "attachments" do |t| 2 t.integer 'parent_id' 3 t.string 'content_type' 4 t.string 'filename' 5 t.string 'thumbnail' 6 t.integer 'size' 7end
obviously it will probably need some kind of relationship to other data in your app.
Thank you, sir! This is a life saver!
By the way, what does @attachment.create({…}) do?
Thanks!
Sorry, typo. It should be Attachment.create({…}).
Sorry for the spam message. I found the answer here – http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M002214.
Thanks again for the great work!
i`ve been loking for this tutorial thanks!!!!!
but i have some problem when i upload my pics becouse there is no error but my app never upload the pics
this is my model maybe it have some wrong
class Image < ActiveRecord::Base
belongs_to :record, :polymorphic => true
has_attachment :content_type => :image,
:storage => :file_system,
:path_prefix => ‘public/records’
validates_as_attachment
end
Please help me!!!!!
Well, it’s hard to tell for sure what your problem might be. But, from looking at your Image class, Imageable module, and view, there are a couple things that jump out at me. Perhaps one of these will help guide you to a solution.
First, your module is set up to only process a single image (has_one :image). Yet your view supports multiple files.
Second, your module’s uploaded_data= method suggests that you’re trying to cause uploaded_data to be a virtual attribute on a model. That’s a nice idea. However, your form is going to pass the file upload data as only attachment_data[], not inmueble[attachment_data][] which is probably what your controller is expecting. I’m not sure on this though as I haven’t seen your controller.
You may find it helpful to look at your development.log. Specifically, look at the incoming parameters for the POST request from your form submission. See if everything is coming in as you are expecting.
Hope that gets you on the path to getting this working.
—t
and this module is my lib/imageable.rb
module Imageable
def self.included(base)
base.class_eval do
has_one :image, :dependent => :destroy, :as => :record
end
end
def uploaded_data=(data)
unless data.blank?
image.destroy if image
self.reload
create_image :uploaded_data => data
end
end
end
sorry, now it`s look better
module Imageable
def self.included(base)
base.class_eval do
has_one :image, :dependent => :destroy, :as => :record
end
end
def uploaded_data=(data)
unless data.blank?
image.destroy if image
self.reload
create_image :uploaded_data => data
end
end
end
and there is my view
<h1>Editing inmueble</h1><% form_for @inmueble, :html => {:multipart => true} do |f| >
<p> <%= f.label :tipo %><br /> <%= f.text_field :tipo %> </p> <p> <%= f.label :descripcion %><br /> <%= f.text_area :descripcion %> </p> <p><= f.error_messages %>
<b>Image</b><br /> <%= file_field_tag ‘attachment_data[]’ >
</p> <p> <%= f.label :ciudad %><br /> <%= f.text_field :ciudad %> </p> <p> <%= f.label :barrio %><br /> <%= f.text_field :barrio %> </p> <p> <%= f.label :direccion %><br /> <%= f.text_field :direccion %> </p> <p> <%= f.label :precio %><br /> <%= f.text_field :precio %> </p> <p> <%= f.submit ‘Update’ %> </p><= file_field_tag ‘attachment_data[]’ >
<= file_field_tag ‘attachment_data[]’ %>
<% end %>
<%= link_to ‘Show’, @inmueble > |
<= link_to ‘Back’, inmuebles_path %>
please you can upload the folder app or send me by mail
please helpp!! i will apreciate
I’m not able to upload the app. Did you see my reply above? If so, what part is still giving you trouble?
—t
ok i just work with more simple example that i will be implement in the same way on my first app
now it is work for me becouse my files are uploaded but i cant related them
i have products ans images
this are the migrate files
products
class CreateProducts < ActiveRecord::Migration
t.timestamps end end def self.down drop_table :products enddef self.up
create_table :products do |t|
t.string :title
t.text :description
t.integer :price
end
images I related this table with products with the field product_id
class CreateImages < ActiveRecord::Migration
def self.down drop_table :images enddef self.up
create_table :images do |t|
t.integer :parent_id, :size, :width, :height, :product_id
t.string :content_type, :filename, :thumbnail
t.timestamps
end
end
end
controller
def update
@product = Product.find(params[:id])
product_id = @product.id
@attachment = Image.new
params[:attachment_data] ||= []
params[:attachment_data].each do |file|
@attachment = Image.create({:uploaded_data => file}) unless file == ""
end
my view products/edit.html.erb
<h1>Editing product</h1><% form_for @product, :html => {:multipart => true} do |f| >
<p> <%= f.label :title %><br /> <%= f.text_field :title %> </p> <p> <%= file_field_tag ‘attachment_data[]’ %><= f.error_messages %>
<%= file_field_tag ‘attachment_data[]’ >
</p> <p> <%= text_field_tag(‘product_id’,@product.id)%>? </p> <p> <%= f.label :description %><br /> <%= f.text_area :description %> </p> <p> <%= f.label :price %><br /> <%= f.text_field :price %> </p> <p> <%= f.submit ‘Update’ %> </p><= file_field_tag ‘attachment_data[]’ %>
<% end %>
<%= link_to ‘Show’, @product > |
<= link_to ‘Back’, products_path %>
how i can pass my @product.id to the field in my database product_id to each file that i upload in the view
please help me!!!
Your view and model look okay I think. Try this for your controller though:
1def update 2 @product = Product.find(params[:id]) 3 product_id = @product.id 4 @attachment = Image.new 5 params[:attachment_data] ||= [] 6 params[:attachment_data].each do |file| 7 @attachment = @product.images.create({:uploaded_data => file}) unless file == ”” 8 end 9end
Notice near the end the change from Image.create to @product.images.create. This will create the association you need.
Let me know how it goes.
—t
<% form_for @product, :html => {:multipart => true} do |f| >
<p> <%= f.label :title %><br /> <%= f.text_field :title %> </p> <p> <%= file_field_tag ‘attachment_data[]’ %><= f.error_messages %>
<%= file_field_tag ‘attachment_data[]’ >
</p> <p> <%= text_field_tag(‘product_id’,@product.id)%> </p> <p> <%= f.label :description %><br /> <%= f.text_area :description %> </p> <p> <%= f.label :price %><br /> <%= f.text_field :price %> </p> <p> <%= f.submit ‘Update’ %> </p><= file_field_tag ‘attachment_data[]’ %>
<% end %>
<%= link_to ‘Show’, @product > |
<= link_to ‘Back’, products_path %>
how i can relate every file that i upload to my images database in the product_id field becouse now it always is null
Thanks a million.
It saved a lot of time for me. Good work!!!
Thanks a lot.. u are so good..!!