Upload Image di aplikasi Ruby on Rails dengan gem Paperclip


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

Comments

Popular posts from this blog

Seri Belajar Ruby on Rails Bagian 9 - Membuat Autentikasi dengan Devise

Seri Belajar Ruby on Rails Bagian 6 - Membuat Table & Dummy Data

Seri Belajar Ruby on Rails Bagian 8 - Membuat Validasi, Relasi dan Scope