Belajar Ruby on Rails - Forms & Strong Parameters
Episode 8 of 27

Belajar Ruby on Rails - Forms & Strong Parameters

Membedah form Rails: form_with sebagai helper form terintegrasi model, nested forms untuk relasi has_many, file upload, serta strong parameters dengan require/permit dan params.expect sebagai perlindungan mass assignment

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 7 kalian memahami view dan template, episode 8 membahas titik pertemuan antara view dan controller: forms. Form adalah pintu masuk data pengguna ke aplikasi — dan karena itu juga pintu masuk utama bagi serangan jika tidak dikelola dengan benar.

Mengapa episode ini penting? Karena form melibatkan tiga lapisan sekaligus: ERB (menampilkan form), controller (membaca dan whitelist data), dan model (validasi & persist). Episode 8 memastikan ketiganya tersambung dengan benar, sekaligus mengenalkan strong parameters — mekanisme yang memblokir mass assignment berbahaya sejak 2012 dan tetap menjadi fondasi keamanan Rails hingga kini.

form_with: Form yang Sadar Model

Helper form utama Rails adalah form_with. Ketika diberi objek model, ia otomatis menyimpulkan action, method, dan field:

HTMLapp/views/posts/_form.html.erb
<%= form_with model: @post do |form| %>
  <% if @post.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@post.errors.count, "error") %>:</h2>
      <ul>
        <% @post.errors.each do |error| %>
          <li><%= error.full_message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
 
  <div>
    <%= form.label :title %>
    <%= form.text_field :title %>
  </div>
 
  <div>
    <%= form.label :body %>
    <%= form.text_area :body %>
  </div>
 
  <%= form.submit %>
<% end %>

Kecerdasan form_with model: @post:

  • @post baru → POST /posts (action create).
  • @post sudah tersimpan → PATCH /posts/:id (action update).
  • Nama field disimpulkan dari atribut model: post[title].

Note

Rails 8 memakai form_with sebagai default. form_for/form_tag (Rails 5) sudah dihapus — jika menemui tutorial lama yang memakainya, konversikan ke form_with.

Strong Parameters: require & permit

Ketika form disubmit, browser mengirim POST /posts dengan payload post[title], post[body]. Controller membaca dan menyaring data ini. Inilah strong parameters:

RubyStrong parameters klasik
def post_params
  params.require(:post).permit(:title, :body)
end
  • require(:post) — memaksa payload punya key post, jika tidak → ActionController::ParameterMissing.
  • permit(:title, :body) — hanya kolom yang terdaftar yang boleh masuk; sisanya diabaikan.

params.expect (Rails 8)

Rails 8 menawarkan params.expect — versi yang lebih eksplisit dan membutuhkan kehadiran key dengan cara yang lebih tegas:

Rubyparams.expect (Rails 8)
def post_params
  params.expect(post: [:title, :body])
end

expect menangani nested object dengan lebih rapi dan melempar error yang lebih jelas saat struktur payload tidak sesuai. Untuk form sederhana, keduanya setara; untuk form kompleks, expect lebih ringkas.

Mengapa Ini Perlindungan Mass Assignment

Tanpa strong params, kode berbahaya ini mungkin terjadi:

RubyInsecure: semua kolom dipakai
@post = Post.new(params[:post]) # DANGER: user bisa set admin/role!

Jika tabel posts punya kolom user_id atau published, penyerang bisa mengirim POST /posts dengan post[user_id]=999 atau post[published]=true dan menguasai data. Strong params memblokir kolom yang tidak terdaftar — hanya kolom yang kalian setujui yang sampai ke model.

Danger

Jangan pernah memanggil Post.create(params[:post]) atau assign_attributes tanpa strong params. Walaupun kolom sensitif tidak tampil di form, penyerang tetap bisa mengirim payload manual lewat curl — strong params adalah satu-satunya garis pertahanan di sisi ini.

Nested Forms: Relasi has_many

Untuk form yang menyimpan relasi sekaligus (misal post + comments), Rails menyediakan nested attributes. Pertama, model menyetujui:

RubyModel mengizinkan nested
class Post < ApplicationRecord
  has_many :comments
  accepts_nested_attributes_for :comments, reject_if: :all_blank
end

Lalu form menampilkannya:

HTMLNested form di _form.html.erb
<%= form.fields_for :comments do |comment_form| %>
  <div>
    <%= comment_form.label :body, "Komentar" %>
    <%= comment_form.text_area :body %>
  </div>
<% end %>

Dan controller whitelist nested key:

RubyPermit nested attributes
def post_params
  params.expect(post: [:title, :body, comments_attributes: [:id, :body, :_destroy]])
end

:id diperlukan agar update menemukan record yang sesuai; :_destroy mengizinkan penghapusan. reject_if: :all_blank mencegah komentar kosong tersimpan.

File Upload dalam Form

File upload di form Rails dikombinasikan dengan Active Storage (dibahas penuh di episode 13). Polanya:

HTMLForm dengan file upload
<%= form_with model: @post, multipart: true do |form| %>
  <%= form.label :cover_image %>
  <%= form.file_field :cover_image %>
<% end %>

multipart: true wajib agar browser mengirim file. Di controller, file masuk sebagai objek ActionDispatch::Http::UploadedFile pada params yang di-permit.

Menangani Validasi Gagal di Form

Alur lengkap form + validasi:

RubyController create dengan render :new
def create
  @post = Post.new(post_params)
 
  if @post.save
    redirect_to @post, notice: "Post berhasil dibuat"
  else
    render :new, status: :unprocessable_entity
  end
end

Saat validasi gagal, render :new menampilkan kembali form berisi data lama (karena @post diisi), plus error dari @post.errors. Status :unprocessable_entity (422) memberi tahu browser bahwa isi tidak valid — alih-alih status sukses yang membingungkan.

Common Pitfalls

  • Lupa menambah kolom baru ke permit/expect — kolom baru di form diam-diam diabaikan; selalu update post_params saat menambah field.
  • params[:post] tanpa strong params — celah mass assignment klasik.
  • Nested form tanpa :id di permit — update relasi jadi gagal atau membuat duplikat.
  • File field tanpa multipart: true — file tidak terkirim, params kosong.
  • Memvalidasi presence di form tapi field tidak di-permit — pengguna melihat error aneh; jaga konsistensi whitelist dan form.

Penutup

Episode 8 membekali kalian form Rails: form_with model: yang menyimpulkan action dan field, strong parameters (require/permit dan params.expect) sebagai garis pertahanan mass assignment, nested forms untuk relasi has_many, file upload, serta pola render ulang form saat validasi gagal.

Inti yang harus dibawa pulang:

  • form_with model: @post otomatis memilih POST/PATCH sesuai status save.
  • Strong params: params.expect(post: [...]) — hanya kolom yang di-whitelist yang masuk model.
  • Mass assignment diblokir oleh whitelist; jangan pernah Post.new(params[:post]).
  • Nested forms butuh accepts_nested_attributes_for + permit comments_attributes.
  • Validasi gagal → render :new, status: :unprocessable_entity.

Di episode 9 selanjutnya kita akan membedah authentication & authorizationhas_secure_password, session & cookies, Rails Authentication generator, Pundit untuk policies dan role-based access. Sampai jumpa di episode 9!

Belajar Ruby on Rails - Forms & Strong Parameters | Belajar Ruby on Rails