Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Ruby on Rails
Code

Mengunggah File Dengan Rails dan Dragonfly

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Yosef Andreas (you can also view the original English article)

Beberapa waktu lalu saya menuliskan sebuah artikiel Mengunggah File Dengan Rails dan Shrine yang menjelaskan bagaimana memperkenalkan sebuah fitur pengunggah file ke dalam aplikasi Rails dengan bantuan Shrine gem. Bagaimana pun juga, ada beberapa solusi serupa yang tersedia, dan salah satu favorit saya adalah Dragonfly—sebuah solusi pengunggah yang mudah digunakan untuk Rails dan Rack yang dibuat oleh Mark Evans.

Kami membahas libary ini lebih awal pada tahun lalu namun, seperti dengan kebanyakan software, itu membantu melihat sebuah library dari waktu ke waktu untuk melihat apa yang telah berubah dan bagaimana kita dapat menerapkannya dalam aplikasi kita.

Di dalam artikel ini saya akan membimbingmu melalui pengaturan Dragonfly dan menjelaskan bagaimana memanfaatkan fitur utamanya. Kamu akan belajar bagaimana:

  • Memadukan Dragonfly ke dalam aplikasimu
  • Mengkonfigurasi model untuk dikerjakan dengan Dragonfly
  • Memperkenalkan mekanisme pengunggah dasar
  • Memperkenalkan validasi
  • Membuat thumbnail gambar
  • Melakukan pemrosesan file
  • Menyimpan metadata untuk file yang diunggah
  • Menyiapkan sebuah aplikasi untuk penyebaran

Untuk membuatnya lebih menarik, kita akan membuat aplikasi kecil musik. Itu akan menyajikan album dan lagu terkait yang dapat dikelola dan dimainkan pada website.

Kode sumber untuk artikel ini tersedia di GitHub. Kamu juga dapat memeriksa demo aplikasi tersebut.

Membuat Daftar dan Mengelola Album

Untuk memulai, buat sebuah aplikasi Rails baru tanpa paket pengujian default:

Untuk artikel ini saya akan menggunakan Rails 5, namun kebanyakan konsep yang dijelaskan berlaku juga untuk versi yang lebih lama.

Membuat Model, Controller, dan Routes

Situs musikal kecil kita akan berisi dua model: Album dan Song. Untuk sekarang, mari kita buat yang pertama dengan isian berikut:

  • title (string)—berisi judul album
  • singer (string)—pelaku album
  • image_uid (string)—sebuah isian spesial untuk menyimpan gambar pratinjau album. Isian ini dapat dinamai apapun yang kamu suka, namun itu harus berisi akhiran _uid seperti yang diinstruksikan dalam dokumentasi Dragonfly.

Buat dan terapkan masing-masing migrasi:

Sekarang mari kita buat controller yang sangat umum untuk mengelola album dengan semua tindakan default:

albums_controller.rb

Terakhir, tambahkan route:

config/routes.rb

Memadukan Dragonfly

Waktunya bagi Dragonfly untuk melangkah ke dalam pusat perhatian. Pertama, tambahkan gem ke dalam Gemfile:

Gemfile

Jalankan:

Perintah terakhir akan membuat initializer bernama dragonfly.rb dengan konfigurasi default. Kita akan mengesampingkan itu dulu untuk saat ini, namun kamu dapat membaca tentang berbagai pilihan di website resmi Dragonfly.

Hal penting berikutnya untuk dilakukan adalah melengkapi model kita dengan metode Dragonfly. Ini dapat dilakukan dengan menggunakan dragonfly_accessor:

models/album.rb

Perhatikan bahwa di sini saya mengatakan :image—itu secara langsung terkait pada kolom image_uid yang kita buat di dalam bagian sebelumnya. Jika kamu, sebagai contoh, menamai kolommu photo_uid, maka metode dragonfly_accessor akan perlu menerima :photo sebagai sebuah argument.

Jika kamu menggunakan Rails 4 atau 5, langkah penting lainnya adalah menandai isian :image (bukan :image_uid!) sebagai yang diizinkan di dalam controller:

albums_controller.rb

Ini sudah cukup—kita siap membuat view dan mulai mengunggah file kita!

Membuat Views

Mulai dengan index view:

views/albums/index.html.erb

Sekarang bagian parsial:

views/albums/_album.html.erb

Ada dua metode Dragonfly untuk dicatat di sini:

  • album.image.url mengembalikan jalur ke gambar.
  • album.image_stored? mengatakan apakah rekaman telah mengunggah file pada tempatnya.

Sekarang tambahkan halaman baru dan edit halaman:

views/albums/new.html.erb

views/albums/edit.html.erb

views/albums/_form.html.erb

Form ini tidak ada yang menarik, namun sekali lagi perhatikan bahwa kami mengatakan :image, bukan :image_uid, ketika menerjemahkan input file.

Sekarang kamu dapat melakukan boot pada server dan menguji fitur pengunggahan!

Menghapus Gambar

Sehingga pengguna dapat membuat dan mengedit album, namun ada sebuah masalah: mereka tidak memiliki cara untuk menghapus gambar, hanya menggantinya dengan yang lainnya. Untungnya, ini sangat mudah diperbaiki dengan memperkenalkan kotak centang "remove image":

views/albums/_form.html.erb

Jika album memiliki gambar terkait, kita menampilkannya dan menerjemahkan sebuah kotak centang. Jika kotak centang ini diatur, gambar akan dihapus. Perhatikan bahwa isianmu bernama photo_uid, kemudian metode terkait untuk menghapus lampiran akan berupa remove_photo. Sederhana, bukan?

Satu-satunya hal lainnya untuk dilakukan adalah mengijinkan atribut remove_image di dalam controller:

albums_controller.rb

Menambahkan Validasi

Pada tahapan ini, semuanya berkerja dengan baik, namun kita tidak memeriksa input pengguna sama sekali, yang tidak terlalu bagus. Karena itu, mari tambahkan validasi untuk model Album:

models/album.rb

validates_property adalah metode Dragonfly yang memeriksa berbagai aspek lampiranmu: kamu mungkin memvalidasi sebuah ekstensi, jenis MIME, ukuran file, dll.

Sekarang mari kita buat parsial umum untuk menerjemahkan error yang kita temukan:

views/shared/_errors.html.erb

Masukkan parsial ini di dalam form:

views/albums/_form.html.erb

Terapkan style isian dengan error sedikit untuk menggambarkannya secara visual:

stylesheets/application.scss

Mempertahankan Gambar Di Antara Permintaan

Dengan memperkenalkan validasi, kita memasuki permasalahan lainnya (skenario yang cukup umum, eh?): jika pengguna telah membuat kesalahan sementara mengisi form, dia akan perlu memilih file lagi setelah mengklik tombol Submit.

Dragonfly dapat membantumu memecahkan masalah ini dengan menggunakan isian retained_* yang tersembunyi:

views/albums/_form.html.erb

Jangan lupa untuk memberikan izin pada isian ini:

albums_controller.rb

Sekarang gambar akan dipertahankan di antara permintaan! Namun satu-satunya masalah kecil adalah bahwa input unggah file akan tetap menampilkan pesan "choose a file", namun ini dapat diperbaiki dengan beberapa styling dan sebuah JavaScript.

Memproses Gambar

Membuat Thumbnail

Gambar yang diunggah oleh pengguna dapat memiliki dimensi yang berbeda, yang dapat (dan mungkin akan) menyebabkan dampak negatif pada desain website. Kamu mungkin ingin mengecilkan skala gambar pada dimensi tetap, dan tentu saja ini mungkin dengan memanfaatkan style width dan height. Ini bagaimana pun juga, bukan sebuah pendekatan optimal: browser akan tetap perlu mengunduh gambar ukuran penuh dan kemudian menyusutkannya.

Pilihan lainnya (yang biasanya jauh lebih baik) adalah menghasilkan thumbnail gambar dengan beberapa dimensi yang telah ditentukan pada server. Ini sangat sederhana untuk dicapai dengan Dragonfly:

views/albums/_album.html.erb

250x250 tentu saja, adalah dimensi, dimana # adalah geometri yang berarti "ubah ukuran dan crop jika perlu untuk mempertahankan aspect ratio terhadap titik pusat". Kamu dapat menemukan informasi tentang geometri lainnya pada website Dragonfly.

Metode thumb diperkuat oleh ImageMagick—sebuah solusi bagus untuk membuat dan memanipulasi gambar. Karena itu, untuk melihat demo secara lokal, kamu perlu menginstal ImageMagick (didukung semua plaftorm besar).

Dukungan untuk ImageMagick diaktifkan secara default di dalam initializer Dragonfly:

config/initializers/dragonfly.rb

Sekarang thumbnail dibuat, namun mereka tidak disimpan dimana pun. Ini berarti tiap kali pengguna mengunjungi halaman album, thumbnail akan dibuat. Ada dua cara untuk mengatasi masalah ini: dengan membuatnya setelah rekaman disimpan atau dengan melakukan pembuatan sambil berlalu.

Pilihan pertama melibatkan pengenalan sebuah kolom baru untuk menyimpan thumbnail dan menyesuaikan metode dragonfly_accessor. Buat dan terapkan migrasi baru:

Sekarang modifikasi modelnya:

models/album.rb

Perhatikan bahwa yang panggilan pertama ke dragonfly_accessor mengirimkan sebuah blok yang sebenarnya membuat thumbnail bagi kita dan menyalin itu ke dalam image_thumb. Sekarang cukup gunakan metode image_thumb di dalam tampilanmu:

views/albums/_album.html.erb

Solusi ini yang paling sederhana, namun tidak direkomendasikan oleh dokumentasi resmi dan, yang lebih buruk lagi, pada waktu penulisan artikel ini itu tidak berkerja dengan isian retained_*.

Karena itu, biarkan saya menunjukkanmu pilihan lainnya: menghasilkan thumbnail sambil berlalu. Itu melibatkan pembuatan model baru dan menyesuaikan file config Dragonfly. Pertama, modelnya:

Tabel thumbs akan menjadi induk thumbnail, namun mereka akan dibuat pada saat permintaan. Untuk membuat ini terjadi, kita perlu menentukan ulang metode url di dalam initializer Dragonfly:

config/initializers/dragonfly.rb

Sekarang tambahkan album baru dan kunjungi halaman root. Pertama kalinya kamu melakukan itu, output berikut akan dicetak ke dalam log:

Ini secara efektif berarti bahwa thumbnail dibuat untuk kita oleh ImageMagick. Jika kamu memuat ulang halaman, baris ini tidak akan muncul lagi, yang berarti bahwa thumbnail mengalami cached! Kamu dapat membaca sedikit lebih lanjut tentang fitur ini di website Dragonfly.

Pemrosesan Lainnya

Kamu dapat melakukan manipulasi apapun secara virtual pada gambarmu setelah mereka diunggah. Ini dapat dilakukan di dalam callback after_assign. Sebagai contoh, mari kita konversi semua gambar kita ke dalam format JPEG dengan kualitas 90%:

Ada lebih banyak tindakan yang dapat kamu lakukan: memutar dan crop gambar, melakukan encode dengan format yang berbeda, menuliskan teks padanya, mencampurkan dengan gambar lainnya (sebagai contoh, untuk menempatkan watermark), dll. Untuk melihat beberapa contoh lainnya, acukan ke bagian ImageMagick pada website Dragonfly.

Mengunggah dan Mengelola Lagu

Tentu saja, bagian utama situs musikal kita adalah lagu, jadi mari tambahkan itu sekarang. Tiap lagu memiliki sebuah judul dan file musikal, dan itu menjadi milik sebuah album:

Gunakan metode Dragonfly, seperti yang kita lakukan untuk model Album:

models/song.rb

Jangan lupa untuk menetapkan relasi has_many:

models/album.rb

Tambahkan route baru. Sebuah lagu selalu ada di dalam lingkup album, jadi saya akan route ini disarangkan:

config/routes.rb

Buat sebuah controller yang sangat sederhana (sekali lagi, jangan lupa memberikan ijin pada isian track):

songs_controller.rb

Tampilkan lagu dan tautan untuk menambahkan yang baru:

views/albums/show.html.erb

Buat code form tersebut:

views/songs/new.html.erb

Terakhir, tambahkan parsial  _song:

views/songs/_song.html.erb

Di sini saya menggunakan tag audio HTML5, yang tidak akan berkerja untuk browser yang lebih tua. Jadi, jika kamu bertujuan mendukung browser itu, gunakan polyfill.

Seperti yang kamu lihat, keseluruhan proses sangat langsung pada tujuan. Dragonfly tidak benar-benar peduli jenis file apa yang kamu ingin unggah; yang perlu kamu lakukan adalah menyediakan metode dragonfly_accessor, menambahkan isian yang sesuai, memberinya ijin, dan menerjemahkan tag input file.

Menyimpan Metadata

Ketika saya membuka saya playlist, saya mengharapkan melihat beberapa informasi tambahan tentang tiap lagu, seperti durasi atau bitrate. Tentu saja, secara default info ini tidak disimpan dimana pun, namun kita dapat memperbaikinya dengan cukup mudah. Dragonfly memungkinkan kita untuk menyediakan data tambahan tentang tiap file yang diunggah dan menarik itu nantinya dengan menggunakan metode meta.

Namun itu menjadi lebih kompleks ketika kita berkerja dengan audio atau video, karena untuk menarik metadata, diperlukan sebuah gem khusus steamio-ffmpeg. Gem ini, sebagai gantinya, bergantung pada FFmpeg, sehingga untuk melanjutkan kamu akan perlu menginstalnya pada PC.

Tambahkan streamio-ffmpeg ke dalam Gemfile:

Gemfile

Install itu:

Sekarang kita dapat menerapkan callback after_assign yang sama dengan yang telah dilihat di bagian sebelumnya:

models/song.rb

Perhatikan bahwa di sini saya menggunakan metode path, bukan url, karena pada titik ini kita berkerja dengan sebuah tempfile. Berikutnya kita hanya mengekstrak durasi lagu (mengkonversinya ke menit dan detik dengan pemandu angka nol) dan bitrate (mengkonversinya ke kilobytes per detik).

Terakhir, tampilkan metadata di dalam tampilan:

views/songs/_song.html.erb

Jika kamu memeriksa konten pada folder public/system/dragonfly (lokasi default untuk menjadi induk unggahan), kamu akan memperhatikan beberapa file .yml—mereka menyimpan semua informasi meta di dalam format YAML.

Menyebarkan ke Heroku

Topik terakhir yang akan kita bahas hari ini adalah bagaimana menyiapkan aplikasimu sebelum menyebarkan ke platform cloud Heroku. Permasalahan utamanya adalah bahwa Heroku tidak mengijinkanmu untuk menyimpan file custom (seperti ungaahan), sehingga kita harus bergantung pada layanan penyimpanan cloud seperti Amazon S3. Untungnya, Dragonfly dapat dipadukan dengan itu secara mudah.

Yang perlu kamu lakukan adalah mendaftarkan akun baru di AWS (jika kamu belum memilikinya), buat sebuah user dengan ijin untuk mengakses S3 bucket, dan tuliskan pemasangan kunci pengguna di dalam lokasi yang aman. Kamu mungkin menggunakan pemasangan kunci root, namun ini sangat tidak direkomendasikan. Terakhir, buat sebuah S3 bucket.

Kembali ke aplikasi Rails, jatuhkan sebuah gem baru:

Gemfile

Install itu:

Kemudian sesuaikan konfigurasi Dragonfly untuk menggunakan S3 di dalam lingkungan produksi:

config/initializers/dragonfly.rb

Untuk menyediakan variabel ENV pada Heroku, gunakan perintah ini:

Jika kamu ingin menguji integrasi dengan S3 secara lokal, kamu mungkin menggunakan gem seperti dotenv-rails untuk mengelola variabel lingkungan. Namun ingatlah, bahwa pemasangan kunci AWS tidak boleh diekspos secara publik!

Permasalahan kecil lainnya yang saya alami ketika menyebarkan ke Heroku adalah tidak adanya FFmpeg. Masalahnya adalah ketika sebuah aplikasi baru Heroku dibuat, itu memiliki serangkaian layanan yang umumnya digunakan (sebagai contoh, ImageMagick tersedia secara default). Layanan lainnya dapat diinstal sebagai Heroke addon atau di dalam bentuk buildpacks. Untuk menambahkan FFmpeg buildpack, jalankan perintah berikut:

Sekarang semuanya telah siap, dan kamu dapat membagikan aplikasi musikalmu dengan dunia!

Kesimpulan

Ini perjalanan yang panjang, bukan? Hari ini kita telah mendiskusikan Dragonfly—sebuah solusi untuk mengunggah file di dalam Rails. Kita telah melihat pengaturan dasarnya, beberapa pilihan konfigurasi, pembuatan thumbnail, pemrosesan, dan penyimpanan metadata. Juga, kita telah memadukan Dragonfly dengan layanan Amazon S3 dan mempersiapkan aplikasi kita untuk penyebaran pada produksi.

Tentu saja, kita belum mendiskusikan semua aspek Dragonfly di dalam artikel ini, jadi pastikan untuk menjelajah website resminya untuk menemukan dokumentasi lanjutan dan contoh-contoh yang berguna. Jika kamu memiliki pertanyaan lainnya atau tersendat dengan beberapa contoh code, jangan ragu untuk menghubungi saya.

Terima kasih telah bersama saya, dan sampai jumpa lagi!

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.