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

Meng-upload file dengan Rails dan Shrine

by
Difficulty:IntermediateLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Imam Firmansyah (you can also view the original English article)

Ada banyak file yang mengunggah gem di luar sana seperti CarrierWavePaperclip, dan Dragonfly dan lain-lain. Mereka semua memiliki spesifikasinya, dan mungkin anda sudah menggunakan setidaknya satu dari gem tersebut.

Hari ini, saya ingin memperkenalkan solusi yang relatif baru, tetapi sangat keren disebut Shrine, yang dibuat oleh Janko Marohnić. Berbeda dengan beberapa gem lain yang serupa, Shrine memiliki pendekatan modular, yang berarti setiap fitur dikemas sebagai modul (atau plugin dalam terminologi Shrine). Ingin mendukung validasi? Tambahkan sebuah plugin. Ingin melakukan beberapa pemrosesan file? Tambahkan sebuah plugin! Saya sangat menyukai pendekatan ini karena memungkinkan anda untuk dengan mudah mengontrol fitur mana yang akan tersedia untuk model yang mana.

Dalam artikel ini saya akan menunjukkan kepada Anda bagaimana untuk:

  • mengintegrasikan Shrine ke dalam aplikasi Rails
  • mengkonfigurasi (secara global dan per-model)
  • menambahkan kemampuan untuk mengunggah file
  • memproses file
  • menambahkan aturan validasi
  • menyimpan additional metadata dan menggunakan cloud storage dengan Amazon S3

Kode sumber untuk artikel ini tersedia di GitHub.

File demo dapat ditemukan disini.

Mengintegrasi Shrine

Untuk memulai, buat aplikasi Rails baru tanpa default testing suite:

Saya akan menggunakan Rails 5 untuk demo ini, tetapi sebagian besar konsep berlaku untuk versi 3 dan 4 juga.

Drop Kuil permata ke Gemfile Anda:

Lalu jalankan:

Sekarang kita akan membutuhkan model yang akan saya sebut Photo. Kuil ini menyimpan semua file yang berhubungan dengan informasi dalam kolom teks khusus mengakhiri dengan akhiran _data. Buat dan terapkan migration yang sesuai:

Perhatikan bahwa untuk versi Rails yang lebih lama, penulisan perintah migration harus:

Opsi konfigurasi untuk Shrine dapat diatur secara global dan per-model. Pengaturan global sudah kita lakukan, tentu saja, di dalam file initializer. Di sana saya akan menghubungkan file-file yang dibutuhkan dan plugins. Plugin digunakan di Shrine untuk mengekstrak potongan-potongan fungsionalitas ke dalam modul terpisah, memberi Anda kontrol penuh atas semua fitur yang tersedia. Sebagai contoh, ada plugin untuk validasi, pemrosesan gambar, cache attachment, dan banyak lagi.

Untuk saat ini, mari tambahkan dua plugin: satu untuk mendukung ActiveRecord dan yang lain untuk mengatur logging. Mereka akan dimasukkan secara global. Dan Juga, mengatur penyimpanan file sistem:

config/initializers/shrine.rb

Logger hanya akan menampilkan beberapa informasi debugging di dalam konsol Anda untuk memberitahukan berapa banyak waktu yang dihabiskan untuk memproses file. Hal ini dapat berguna.

Semua file yang diunggah akan disimpan di dalam direktori public/uploads. Saya tidak ingin melacak file-file ini di Git, jadi kecualikan folder ini:

.gitignore

Sekarang buat "uploader" class khusus yang akan menjadi host pengaturan khusus untuk model. Untuk saat ini, class akan dibiarkan kosong:

models/image_uploader.rb

Terakhir, sertakan class di dalam model Photo:

models/photo.rb

[:image] menambahkan atribut virtual yang akan digunakan saat membuat form. Baris di atas dapat ditulis ulang sebagai:

Bagus! Sekarang model ini dilengkapi dengan fungsi Shrine, dan kita dapat melanjutkan ke langkah berikutnya.

Controller, Views, dan Routes

Untuk keperluan demo ini, kita hanya memerlukan satu controller untuk mengelola foto. Halaman index akan berfungsi sebagai root:

pages_controller.rb

Untuk tampilannya:

views/photos/index.html.erb

Untuk membuat @photos array, diperlukan sebuah partial:

views/photos/_photo.html.erb

image_data? adalah metode yang disajikan oleh Shrine yang memeriksa apakah didalam records terdapat gambar.

image_url adalah metode Shrine lain yang hanya mengembalikan path ke original image. Tentu saja, jauh lebih baik untuk menampilkan thumbnail kecil, tetapi kita akan mengurusnya nanti.

Tambahkan semua route yang diperlukan:

config/routes.rb

Ini dia — dasarnya sudah selesai, dan kita bisa melanjutkan ke bagian yang menarik!

Meng-upload file

Dalam bagian ini, saya akan menunjukkan cara menambahkan fungsionalitas untuk upload file. Controller yang dibutuhkan sangat sederhana:

photos_controller.rb

Satu-satunya cara untuk membuat parameter yang kuat Anda harus mengizinkan attribut image virtual, bukan image_data.

photos_controller.rb

Buatlah new view:

views/photos/new.html.erb

Form partialnya juga sederhana:

views/photos/_form.html.erb

Sekali lagi, perhatikan bahwa kita menggunakan atribut image, bukan image_data.

Terakhir, tambahkan partial lain untuk menampilkan error:

views/shared/_errors.html.erb

Ini cukup — Anda dapat mulai mengunggah gambar sekarang.

Validasi

Tentu saja, masih banyak pekerjaan yang harus dilakukan untuk menyelesaikan aplikasi demo. Masalah utamanya sekarang adalah pengguna dapat mengunggah jenis file apa pun dengan ukuran apa pun, yang tidak terlalu bagus untuk sebuah aplikasi. Oleh karena itu, tambahkan plugin lain untuk mendukung validasi:

config/inititalizers/shrine.rb

Atur logika validasi untuk ImageUploader:

models/image_uploader.rb

Saya hanya mengizinkan gambar JPG dan PNG kurang dari 1MB yang dapat diunggah. Modifikasi aturan-aturan ini sesuai keinginan anda.

MIME Types

Hal penting lainnya yang perlu diperhatikan adalah, secara default, Shrine akan menentukan jenis file MIME menggunakan header HTTP Content-Type. Header ini dilewatkan oleh browser dan hanya disetel berdasarkan ekstensi file.

Jika Anda ingin menentukan jenis MIME berdasarkan konten file, gunakan plugin yang disebut dengan determine_mime_type. Saya akan memasukkannya ke dalam class uploader, karena model lain mungkin tidak memerlukan fungsi ini:

models/image_uploader.rb

Plugin ini akan menggunakan file utility Linux secara default.

Cache Gambar yang Terlampir

Saat ini, ketika pengguna mengirimkan form dengan data yang salah, form akan ditampilkan lagi dengan kesalahan yang dilakukan sebelumnya. Masalahnya adalah gambar yang dilampirkan akan hilang, dan pengguna akan perlu memilihnya sekali lagi. Ini sangat mudah diperbaiki dengan menggunakan plugin lain bernama cached_attachment_data:

models/image_uploader.rb

Sekarang tambahkan sebuah field tersembunyi ke dalam form anda.

views/photos/_form.html.erb

Mengedit Foto

Sekarang gambar dapat diunggah, tetapi tidak ada cara untuk mengeditnya, jadi mari kita segera memperbaikinya. Lakukan perintah sederhana untuk controller:

photos_controller.rb

_form partial yang sama akan digunakan:

views/photos/edit.html.erb

Bagus, tetapi belum cukup: user masih tidak dapat menghapus gambar yang di-upload. Untuk mengijinkan ini, kita perlu plugin lainnya:

models/image_uploader.rb

lugin ini menggunakan atribut virtual yang disebut :remove_image, jadi izinkan atribut ini di dalam controller:

photos_controller.rb

Sekarang tampilkan checkbox untuk menghapus gambar jika record memiliki attachment:

views/photos/_form.html.erb

Membuat Gambar Thumbnail

Saat ini kita menampilkan gambar asli, yang bukan pendekatan terbaik untuk preview: foto mungkin berukuran besar dan menempati terlalu banyak ruang. Tentu saja, Anda bisa menggunakan atribut CSS width dan height, tetapi itu ide yang buruk. Anda lihat bahkan jika gambar diatur menjadi kecil menggunakan style, pengguna masih perlu mengunduh file asli, yang mungkin ukurannya filenya cukup besar.

Oleh karena itu, jauh lebih baik untuk membuat gambar preview kecil dari server selama proses upload awal. Cara ini melibatkan dua plugin dan dua gem tambahan. Pertama, masukkan ke gem:

Image_processing adalah gem khusus yang dibuat oleh pencipta Shrine. Gem ini menyajikan beberapa metode pembantu tingkat tinggi untuk memanipulasi gambar. Gem ini bergantung pada mini_magick, sebuah Ruby wrapper untuk ImageMagick. Seperti yang anda duga, anda perlu ImageMagick di sistem anda untuk menjalankan demo ini.

Instal gem baru:

Sekarang sertakan plugin bersama dengan dependensi mereka:

models/image_uploader.rb

Processing adalah plugin untuk memanipulasi gambar (misalnya, menyusutkan, memutar, mengonversi ke format lain, dll.). Versions memungkinkan kita untuk memiliki gambar dalam berbagai varian. Untuk demo ini, dua versi gambar akan disimpan: "original" dan "thumb" (diubah ukurannya menjadi 300x300).

Berikut adalah kode untuk memproses gambar dan menyimpan kedua versinya:

models/image_uploader.rb

resize_to_limit! adalah metode yang disediakan oleh gem image_processing. Metode ini hanya memperkecil gambar menjadi 300x300 jika ukuran gambar besar dan tidak melakukan apa-apa jika ukuran gambar lebih kecil. Selain itu, metode ini juga menjaga aspek rasio asli.

Sekarang ketika menampilkan gambar, Anda hanya perlu menambahkan argumen :original atau :thumb ke metode image_url:

views/photos/_photo.html.erb

Hal yang sama dapat dilakukan di dalam form:

views/photos/_form.html.erb

Agar sistem secara otomatis menghapus file yang diproses setelah proses menguggah selesai, Anda dapat menambahkan plugin bernama delete_raw:

models/image_uploader.rb

Metadata Gambar

Selain membuat gambar, anda juga dapat mengambil metadatanya. Mari kita, misalnya, menampilkan ukuran foto asli dan MIME type:

views/photos/_photo.html.erb

Bagaimana dengan dimensinya? Sayangnya, mereka tidak disimpan secara default, tetapi hal ini mungkin dengan plugin bernama store_dimensions.

Dimensi Gambar

Plugin store_dimensions bergantung pada gem fastimage gem, jadi hubungkan gem ini sekarang:

Jangan lupa untuk menjalankan:

Sekarang, masukkan plugin:

models/image_uploader.rb

Dan tampilkan dimensi menggunakan metode width dan height:

views/photos/_photo.html.erb

Juga, metode dimensions mengatur dimensi yang tersedia dengan menggunakan array yang berisi width dan height (misalnya, [500, 750]).

Memindahkan ke Cloud

Pengembang sering memilih layanan cloud untuk meng-host file yang diunggah, dan Shrine memang menghadirkan fitur seperti itu. Di bagian ini, saya akan menunjukkan cara mengunggah file ke Amazon S3.

Sebagai langkah pertama, sertakan dua gem lagi ke dalam Gemfile:

aws-sdk diperlukan untuk bekerja dengan SDK S3, sedangkan dotenv-rails akan digunakan untuk mengelola variabel lingkungan dalam pengembangan.

Sebelum melanjutkan, Anda harus mendapatkan key pair untuk mengakses S3 melalui API. Untuk mendapatkannya, masuk (atau daftar) ke Amazon Web Services Console dan bukalah halaman Security Credentials > Users. Buat sebuah user dengan izin untuk memanipulasi file pada S3. Berikut adalah kebijakan sederhana yang mengizinkan akses penuh ke S3:

Unduh key pair user yang dibuat. Alternatif lainnya, anda mungkin menggunakan root access key, tetapi saya sangat tidak menyarankan anda melakukan hal itu karena sangat tidak aman.

Selanjutnya, buat bucket S3 untuk meng-host file Anda dan tambahkan file ke project root untuk meng-host konfigurasi Anda:

.env

Jangan pernah mengekspos file ini ke public dan pastikan anda mengecualikan file ini dari Git:

.gitignore

Sekarang, modifikasi konfigurasi global Shrine dan perkenalkan storage baru:

config/initializers/shrine.rb

Itu dia! Tidak ada perubahan yang harus dilakukan pada bagian lain dari aplikasi, dan Anda dapat segera menguji storage baru ini. Jika Anda menerima pesan eror dari S3 terkait dengan key yang salah, pastikan Anda secara akurat menyalin key dan rahasianya, tanpa spasi tambahan dan simbol khusus yang tidak terlihat.

Kesimpulan

Kita telah sampai di bagian akhir artikel ini. Semoga, sekarang Anda merasa jauh lebih percaya diri dalam menggunakan Shrine dan ingin menggunakannya dalam salah satu proyek Anda. Kita telah membahas banyak fitur gem ini, tetapi ada lebih banyak lagi, seperti kemampuan untuk menyimpan konteks tambahan bersama dengan file dan mekanisme pengunggahan langsung.

Oleh karena itu, bacalah dokumentasi Shrine dan situs resminya, yang secara menyeluruh menjelaskan semua plugin yang tersedia. Jika Anda memiliki pertanyaan lain yang tersisa tentang gem ini, jangan ragu untuk mempostingnya. Terima kasih untuk tetap bersama saya, dan sampai bertemu kembali!

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.