This is dilema untuk developer terutama ruby on rails developer yang punya modal pas-pasan ketika dihadapkan dengan fitur upload file, baik image; video; maupun jenis file lainnya.

Tidak punya kartu kredit, tidak punya vps untuk nge-host aplikasinya juga. Cuma ada akun heroku. Terus harus naruh hasil upload dimana?

Dropbox? Okay, tapi sangat lambat ketika load file nya, dan pasti nemuin masalah file name.
Google drive? Did not try it yet, tapi kelihatannya menjanjikan. Cuma masalahnya google drive tidak diperuntukkan untuk CDN aplikasi, kan?

Nah beberapa minggu lalu / entah bulan (agak lupa kapan), salah seorang teman nge-share tentang cloudinary.

Begitu lihat landing pagenya, saya langsung gini kira-kira :

Wow, ini dia solusi untuk teman-teman RoR developer. Storage…!! storage…!!! No credit card required…!!! Awesome!!!! Must try…!! Must try…!!

Finally, saya diberi kesempatan untuk mencobanya. Tapi ngomong-ngomong saya akan mencobanya di ruby on rails saja, sekalipun saya jago NodeJS & AngularJS juga :P.. Lah, gak percaya? Cek saja KTP saya hahaha :D just kidding!! Masih newbie juga kok om.. :bow:

yuk mari, mulai…!!


Asumsi sudah ada existing things di RoR aplikasi

Jadi disini cuma akan diajari pasang fitur upload, teman-teman bisa lah ya nge-create rails app terus generate file-file-nya.

Kalau misal belum bisa dan pingin belajar, perlu deh stay tune mantengin idrails yang gak akan lama lagi launching, doakan saja :)

Registrasi

Silakan register dulu buat panen beberapa credentials dari cloudinary. Setelah itu akan digiring ke halaman dashboard

dashboard

Setup

Credentials

Ini cukup download file cloudinary.yml yang sudah disediakan. Lalu taruh file tersebut pada config/ directory sejajar dengan database.yml

Cloudinary

  • Tambahkan pada Gemfile :

    1
    gem "cloudinary"
  • Jalankan bundle install. Kemudian coba dicek apakah sudah bisa upload apa belum. Bisa lewat rails c lalu ketik 2.2.3 :002 > Cloudinary::Uploader.upload(<path_to_image>), misalnya :

    1
    2
    2.2.3 :002 > Cloudinary::Uploader.upload('/home/ardian/Pictures/chat.png')
    => {"public_id"=>"q9eahpbpdykbmirlxyya", "version"=>1451546307, "signature"=>"a790b93219dd0054a6078e66de2f4ff84809c46a", "width"=>1319, "height"=>744, "format"=>"png", "resource_type"=>"image", "created_at"=>"2015-12-31T07:18:27Z", "tags"=>[], "bytes"=>142002, "type"=>"upload", "etag"=>"b43dee8bc213c1e9c822d8917ba1f3b7", "url"=>"http://res.cloudinary.com/absyah/image/upload/v1451546307/q9eahpbpdykbmirlxyya.png", "secure_url"=>"https://res.cloudinary.com/absyah/image/upload/v1451546307/q9eahpbpdykbmirlxyya.png", "original_filename"=>"chat"

Kalau output sudah seperti diatas, berarti sudah OK! So far sampai sini mudah, kan? :)

Attachinary

  • Tambah Gem Attachinary
    Attachinary adalah gem wrapper untuk Cloudinary.

    1
    gem 'attachinary'
  • Jalankan bundle install dan pada application.rb, include :

    1
    require "attachinary/orm/active_record" # active_record atau mongoid
  • Run rake attachinary:install:migrations dan rake db:migrate
    Ketika kita eksekusi perintah rake attachinary:install:migrations pada aplikasi kita akan ada new migration seperti ini :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # This migration comes from attachinary (originally 20120612112526)
    class CreateAttachinaryTables < ActiveRecord::Migration
    def change
    create_table :attachinary_files do |t|
    t.references :attachinariable, polymorphic: true
    t.string :scope

    t.string :public_id
    t.string :version
    t.integer :width
    t.integer :height
    t.string :format
    t.string :resource_type
    t.timestamps
    end
    add_index :attachinary_files, [:attachinariable_type, :attachinariable_id, :scope], name: 'by_scoped_parent'
    end
    end
  • Mount attachinary pada routes.rb :

    1
    mount Attachinary::Engine => "/attachinary"
  • Generate file-file javascript yang diperlukan :

    1
    rake attachinary:fetch_fileupload # download required js file
  • Include pada application.js :

    1
    2
    3
    4
    5
    //= require jquery.ui.widget
    //= require jquery.iframe-transport
    //= require jquery.fileupload
    //= require cloudinary/jquery.cloudinary
    //= require attachinary
  • Dan yang terakhir, tambahkan pada header application layout <%= cloudinary_js_config %>
    Application layout akan seperti ini jadinya :

    1
    2
    3
    4
    5
    6
    7
    <head>
    <title>App Keren</title>
    <%= stylesheet_link_tag 'application', media: 'all' %>
    <%= javascript_include_tag 'application' %>
    <%= cloudinary_js_config %>
    <%= csrf_meta_tags %>
    </head>

Setup Model

Misal kita punya model Product, akan kita tambahkan Product has many Images, gak asik kan kalau jualan tapi gak ada imagenya :D

1
2
validates :images, presence: true
has_attachments :images, maximum: 5, accept: [:jpg, :png, :gif]

Nah disini asyiknya, kita gak perlu update migrasi pada Product untuk menambahkan images attribute. Dibandingkan dengan gem-gem lainnya yang kita perlu menambahkan migrasi baru, misalnya pada gem paperclip harus add_attachment :products, :image.

Setup View dan Controller

Pada form Product, tambahkan

1
<%= f.attachinary_file_field :images %>

Dan finally pada controller, tambahkan pada strong parameters. Misalnya :

1
params.require(:product).permit(:name, :price, :description, images: [])

Untuk menampilkannya, pada show.html.erb tambahkan :

1
2
3
<% @product.images.each do |image| %>
<%= cl_image_tag(image.path, { size: '125x125', crop: :fit }) %>
<% end %>

hasil

Screenshot diatas adalah hasil dari coba-coba implementasi upload dengan Cloudinary dan Attachinary. Bisa kelihatan ada image preview ketika kita select image. Selain itu ada progress percentage nya juga ketika proses upload image sedang berlangsung. Awesome, just awesome!!

Summary

Dulu waktu pertama kali coba implementasi fitur upload dengan AWS S3 + Paperclip, saya mencoba beberapa kali sampai berhasil. Ketika saya mencoba implementasi dengan Cloudinary + Attachinary saya merasa inilah kombinasi yang pas dan mudah diterapkan untuk fitur upload dipenghujung akhir tahun ini :)

Satu hal yang terpenting adalah pada Cloudinary tidak membutuhkan credit card hanya untuk sekadar free plan. :D

So, I think Cloudinary is AWS S3 killer. What do you think?