Rails Active Storage 2026: Upload File, Integrasi S3, dan Pertanyaan Interview
Panduan lengkap Rails Active Storage untuk upload file, integrasi Amazon S3, dan persiapan pertanyaan interview Ruby on Rails.

Active Storage merupakan fitur bawaan Ruby on Rails yang menyederhanakan proses upload file dan manajemen attachment. Dengan dukungan cloud storage seperti Amazon S3, Google Cloud Storage, dan Microsoft Azure, Active Storage memberikan solusi lengkap untuk kebutuhan file handling dalam aplikasi web modern.
Dalam panduan ini, pembaca akan mempelajari cara mengimplementasikan upload file dengan Active Storage, mengkonfigurasi integrasi S3, serta mempersiapkan diri untuk pertanyaan interview terkait file handling di Ruby on Rails.
Active Storage telah menjadi standar untuk file handling di Rails sejak versi 5.2. Memahami fitur ini sangat penting untuk setiap developer Rails yang ingin membangun aplikasi production-ready.
Memahami Arsitektur Active Storage
Active Storage menggunakan dua tabel database untuk mengelola attachment: active_storage_blobs dan active_storage_attachments. Tabel blob menyimpan metadata file seperti nama, content type, dan checksum, sedangkan tabel attachment menghubungkan blob dengan model ActiveRecord.
Arsitektur ini memungkinkan satu file di-attach ke multiple record dan mendukung berbagai storage backend tanpa mengubah kode aplikasi.
# Generate Active Storage tables
rails active_storage:install
rails db:migratePerintah di atas membuat migration untuk kedua tabel yang diperlukan Active Storage.
Konfigurasi Model untuk File Upload
Menambahkan attachment ke model Rails sangat sederhana dengan macro has_one_attached dan has_many_attached.
# app/models/user.rb
class User < ApplicationRecord
has_one_attached :avatar
has_many_attached :documents
validates :avatar, content_type: ['image/png', 'image/jpeg'],
size: { less_than: 5.megabytes }
endDengan deklarasi ini, model User dapat menerima satu avatar dan multiple documents.
Implementasi Controller untuk Upload
Controller menangani proses upload dengan memanfaatkan strong parameters untuk menerima file dari form.
# app/controllers/users_controller.rb
class UsersController < ApplicationController
def create
@user = User.new(user_params)
if @user.save
redirect_to @user, notice: 'User created successfully'
else
render :new, status: :unprocessable_entity
end
end
def update
@user = User.find(params[:id])
if @user.update(user_params)
redirect_to @user, notice: 'User updated successfully'
else
render :edit, status: :unprocessable_entity
end
end
private
def user_params
params.require(:user).permit(:name, :email, :avatar, documents: [])
end
endMembuat Form Upload dengan Rails 8
Rails 8 menyediakan form helper yang terintegrasi dengan Active Storage.
<%# app/views/users/_form.html.erb %>
<%= form_with model: @user do |form| %>
<div class="field">
<%= form.label :avatar %>
<%= form.file_field :avatar, accept: 'image/png,image/jpeg',
direct_upload: true %>
</div>
<div class="field">
<%= form.label :documents %>
<%= form.file_field :documents, multiple: true,
direct_upload: true %>
</div>
<%= form.submit %>
<% end %>Atribut direct_upload: true mengaktifkan upload langsung ke storage service tanpa melalui server Rails.
Konfigurasi Amazon S3 untuk Production
Untuk production environment, S3 menjadi pilihan populer karena skalabilitas dan reliabilitasnya.
# config/storage.yml
amazon:
service: S3
access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
region: ap-southeast-1
bucket: myapp-production-uploads
public: falseKonfigurasi di atas menggunakan Rails credentials untuk menyimpan API keys dengan aman.
# config/environments/production.rb
Rails.application.configure do
config.active_storage.service = :amazon
endMenambahkan Gem yang Diperlukan
S3 storage memerlukan gem AWS SDK.
# Gemfile
gem 'aws-sdk-s3', require: false
gem 'image_processing', '~> 1.2'Gem image_processing diperlukan untuk fitur variant seperti resize dan crop gambar.
Image Variants dan Transformasi
Active Storage menyediakan fitur variant untuk mengubah ukuran dan format gambar secara on-demand.
# Generating image variants
@user.avatar.variant(resize_to_limit: [200, 200]).processed
# Pre-defined variants in model
class User < ApplicationRecord
has_one_attached :avatar do |attachable|
attachable.variant :thumb, resize_to_limit: [100, 100]
attachable.variant :medium, resize_to_limit: [300, 300]
attachable.variant :large, resize_to_limit: [800, 800]
end
endVariant dibuat secara lazy dan di-cache untuk request selanjutnya.
Menampilkan Attachment di View
Rails menyediakan helper untuk menampilkan gambar dan file attachment.
<%# Display avatar with variant %>
<%= image_tag @user.avatar.variant(:thumb) if @user.avatar.attached? %>
<%# Link to download document %>
<% @user.documents.each do |document| %>
<%= link_to document.filename, rails_blob_path(document, disposition: 'attachment') %>
<% end %>
<%# Display image with fallback %>
<%= image_tag(@user.avatar.attached? ? @user.avatar.variant(:medium) : 'default-avatar.png') %>Direct Upload dengan JavaScript
Direct upload memungkinkan file dikirim langsung ke storage service, mengurangi beban server Rails.
import { DirectUpload } from "@rails/activestorage"
class DirectUploadController {
constructor(file, url) {
this.directUpload = new DirectUpload(file, url, this)
}
upload() {
return new Promise((resolve, reject) => {
this.directUpload.create((error, blob) => {
if (error) {
reject(error)
} else {
resolve(blob.signed_id)
}
})
})
}
directUploadWillStoreFileWithXHR(request) {
request.upload.addEventListener("progress", event => {
const progress = (event.loaded / event.total) * 100
console.log(`Upload progress: ${progress.toFixed(2)}%`)
})
}
}
export { DirectUploadController }Validasi File dengan Custom Validator
Validasi yang lebih kompleks dapat diimplementasikan dengan custom validator.
# app/validators/file_size_validator.rb
class FileSizeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return unless value.attached?
if value.is_a?(ActiveStorage::Attached::Many)
value.each do |attachment|
validate_attachment(record, attribute, attachment)
end
else
validate_attachment(record, attribute, value)
end
end
private
def validate_attachment(record, attribute, attachment)
max_size = options[:max] || 10.megabytes
if attachment.blob.byte_size > max_size
record.errors.add(attribute, "is too large (max: #{max_size / 1.megabyte}MB)")
end
end
endBackground Processing dengan Active Job
Proses berat seperti video transcoding sebaiknya dilakukan di background.
# app/jobs/process_video_job.rb
class ProcessVideoJob < ApplicationJob
queue_as :default
def perform(video_id)
video = Video.find(video_id)
return unless video.file.attached?
video.file.analyze
# Additional processing logic
end
end
# Trigger job after upload
class Video < ApplicationRecord
has_one_attached :file
after_commit :process_video, on: [:create, :update]
private
def process_video
ProcessVideoJob.perform_later(id) if file.attached?
end
endTesting Active Storage
Rails menyediakan fixtures dan helpers untuk testing Active Storage.
# test/models/user_test.rb
require 'test_helper'
class UserTest < ActiveSupport::TestCase
test 'should attach avatar' do
user = users(:john)
user.avatar.attach(
io: File.open(Rails.root.join('test/fixtures/files/avatar.png')),
filename: 'avatar.png',
content_type: 'image/png'
)
assert user.avatar.attached?
assert_equal 'avatar.png', user.avatar.filename.to_s
end
test 'should validate avatar content type' do
user = users(:john)
user.avatar.attach(
io: File.open(Rails.root.join('test/fixtures/files/document.pdf')),
filename: 'document.pdf',
content_type: 'application/pdf'
)
assert_not user.valid?
assert_includes user.errors[:avatar], 'has an invalid content type'
end
endPertanyaan Interview Active Storage
Berikut pertanyaan umum yang sering muncul dalam interview Ruby on Rails:
Apa perbedaan antara has_one_attached dan has_many_attached?
has_one_attached digunakan untuk single file attachment seperti avatar, sedangkan has_many_attached untuk multiple files seperti gallery atau documents.
Bagaimana Active Storage menyimpan file secara default?
Secara default, Active Storage menggunakan disk service yang menyimpan file di folder storage/ dalam aplikasi. Untuk production, sebaiknya menggunakan cloud storage seperti S3.
Apa itu Direct Upload dan kapan menggunakannya?
Direct Upload memungkinkan browser mengupload file langsung ke storage service tanpa melalui server Rails. Ini berguna untuk file besar karena mengurangi memory usage di server.
Bagaimana cara mengoptimalkan gambar dengan Active Storage?
Gunakan variants untuk membuat versi gambar dengan ukuran berbeda. Variants dibuat secara lazy dan di-cache, sehingga tidak membebani server.
Bagaimana menghapus attachment yang tidak terpakai?
Gunakan task rails active_storage:purge:unattached untuk membersihkan blob yang tidak terhubung ke record manapun.
# Manual purge
ActiveStorage::Blob.unattached.where('created_at < ?', 1.day.ago).find_each(&:purge_later)Siap menguasai wawancara Ruby on Rails Anda?
Berlatih dengan simulator interaktif, flashcards, dan tes teknis kami.
Kesimpulan
Active Storage menyediakan solusi komprehensif untuk file handling di Ruby on Rails. Dengan integrasi cloud storage seperti S3, fitur direct upload, dan image variants, developer dapat membangun sistem upload file yang scalable dan production-ready.
Memahami konsep dasar seperti blob, attachment, dan variants sangat penting untuk interview dan development sehari-hari. Praktik terbaik seperti validasi file, background processing, dan proper testing akan memastikan implementasi yang robust dan maintainable.
Bisakah kamu menemukan bug di Ruby on Rails?
Satu potongan kode nyata, satu bug tersembunyi, satu percobaan per hari. Tanpa akun untuk mencoba.

Ditulis oleh
Anthony Fillion-MailletPendiri SharpSkill
Developer fullstack selama lebih dari 10 tahun. Ia menjalankan SharpSkill dan bertanggung jawab atas semua yang diterbitkan di sini.
Diperbarui 9 September 2026
Bagikan
Artikel terkait

Rails GraphQL API di 2026: graphql-ruby, Subscriptions, dan Pertanyaan Interview
Bangun GraphQL API siap produksi dengan Rails 8 dan graphql-ruby. Desain schema, mutations, subscriptions dengan ActionCable, dan persiapan interview.

Background Jobs Rails di 2026: Sidekiq vs Good Job dan Pertanyaan Interview
Panduan lengkap memilih queue backend untuk Rails: perbandingan Sidekiq 8.x, Good Job 4.x, dan Solid Queue dengan fokus pada throughput, fitur, dan pertanyaan interview teknis.

Rails Stimulus dan Importmaps 2026: JavaScript Modern Tanpa Build Tools
Stimulus dan Importmaps di Rails 8.1 memungkinkan penulisan JavaScript modern tanpa bundler. Tutorial ini membahas controller, action, target, dan package npm.