Pada tulisan kali ini di
belajar Ruby on Rails akan membahas mengenai upload banyak file (multiple upload file). File yang diupload bisa berbagai macam type file, bisa berupa image, text, video, audio, dan dokumen.
Untuk mempermudah kita akan menggunakan gem
paperclip. Contoh kasus yang akan dibahas adalah mengenai upload gambar, misal kita punya produk, dimana produk tersebut mempunyai banyak gambar, dan kita menginginkan bisa mengupload gambar-gambar tersebut saat create produk.
Langkah pertama:
pada gemfile tambahkan script berikut:
gem "paperclip", "~> 3.0"
gem "rmagick"
gem "jquery-rails"
Langkah kedua:
Lakukan bundle install pada console
bundle install
Langkah ketiga:
Buat migration untuk menambahkan field-field yang dibutuhkan oleh paperclip
class AddDataToProductImage < ActiveRecord::Migration
def self.up
add_column :product_images, :data_file_name, :string
add_column :product_images, :data_content_type, :string
add_column :product_images, :data_file_size, :integer
add_column :design_images, :data_updated_at, :datetime
end
def self.down
remove_column :product_images, :data_file_name
remove_column :product_images, :data_content_type
remove_column :product_images, :data_file_size
remove_column :product_images, :data_updated_at
end
end
Langkah keempat:
Jalankan migration pada console
rake db:migrate
Langkah kelima:
Rubah model product, product_image menjadi seperti dibawah:
class Product < ActiveRecord::Base
has_many :product_images
accepts_nested_attributes_for :product_images, :allow_destroy => true
end
class ProductImage < ActiveRecord::Base
belongs_to :product
require 'RMagick'
has_attached_file :data
end
Langkah keenam:
Perubahan pada view, yaitu me-load javascript default dan merubah form
edit file:
app/views/products/_form.html.erb
<%= javascript_include_tag :defaults %>
<script type="text/javascript">
function add_fields(link, association, content) {
var new_id = new Date().getTime();
var regexp = new RegExp("new_" + association, "g");
$("#"+association).append(content.replace(regexp, new_id));
}
</script>
<%= form_for(@product, :html => {:multipart => true}) do |f| %>
<% if @product.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@product.errors.count, "error") %> prohibited this product from being saved:</h2>
<ul>
<% @product.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br />
<%= f.text_area :description %>
</div>
<div id="product_images">
<div class="field">
<%= f.fields_for :product_images do |detail| %>
<%= render "product_image", :f => detail %>
<% end %>
</div>
</div>
<div class="field">
<%= link_to_add_fields "Tambah Gambar", f, :product_images %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
edit file:
app/views/products/_product_image.html.erb
<% if !f.object.new_record? %>
<%= image_tag f.object.data.url(:thumb) %>
<% end %>
<%= f.file_field :data %>
<% if f.object.new_record? %>
<%= link_to_function("Hapus", "$(this).parent('fieldset').remove()") %>
<% else %>
<%= link_to "Hapus gambar", delete_image_products_path(id: f.object.id), method: :delete,
data: { confirm: 'Apakah Anda yakin untuk menghapus gambar?' }
%>
<% end %>
Langkah ketujuh:
Tambahkan script berikut pada
app/helpers/application_helper.rb
def link_to_add_fields(name, f, association)
new_object = f.object.class.reflect_on_association(association).klass.new
fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|
render(association.to_s.singularize, :f => builder)
end
link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")", :class => "addField")
end
Langkah kedelapan:
Tambahkan modul delete image pada
app/controllers/products_controller.rb
def delete_image
@product_image = ProductImage.find(:first, :conditions => ["id = ?", params[:id]])
@product = @product_image.product
if @product
@product_image.destroy
redirect_to :back, :notice => 'Gambar telah berhasil dihapus.'
else
redirect_to products_url, :notice => 'Gambar tidak ditemukan.'
end
end
Langkah terakhir:
Tambahkan script berikut pada file
app/views/products/show.html.erb
<% @product.photos.each do |photo| %>
<%= image_tag photo.data.url %>
<% end %>
Selamat mencoba :)
Referensi :
http://shiningthrough.co.uk/Dynamic-multiple-image-uploads-with-Ruby-on-Rails