The form object pattern helps keep your code clean by separating form handling from your database models. It makes complex forms easier to manage and test.
0
0
Form object pattern in Ruby on Rails
Introduction
When a form needs to update multiple models at once.
When you want to keep your database models simple and focused.
When you have complex validation logic that doesn't fit well in a single model.
When you want to reuse form logic across different parts of your app.
When you want to test form behavior without touching the database.
Syntax
Ruby on Rails
class MyForm include ActiveModel::Model attr_accessor :field1, :field2 validates :field1, presence: true def save return false unless valid? # custom save logic here end end
Use include ActiveModel::Model to get model-like behavior without a database table.
Define attr_accessor for form fields you want to handle.
Examples
A form object for user signup that validates email and password confirmation, then creates a User.
Ruby on Rails
class SignupForm include ActiveModel::Model attr_accessor :email, :password, :password_confirmation validates :email, presence: true validates :password, confirmation: true def save return false unless valid? User.create(email: email, password: password) end end
This form object handles order creation with validations for product and quantity.
Ruby on Rails
class OrderForm include ActiveModel::Model attr_accessor :product_id, :quantity, :user_id validates :product_id, :quantity, presence: true def save return false unless valid? Order.create(product_id: product_id, quantity: quantity, user_id: user_id) end end
Sample Program
This ContactForm object collects user input, validates presence of all fields, and simulates saving by returning true. It prints success or error messages.
Ruby on Rails
class ContactForm include ActiveModel::Model attr_accessor :name, :email, :message validates :name, :email, :message, presence: true def save return false unless valid? # Imagine sending an email here true end end # Usage example form = ContactForm.new(name: "Alice", email: "alice@example.com", message: "Hello!") if form.save puts "Form saved successfully" else puts "Form has errors: #{form.errors.full_messages.join(", ")}" end
OutputSuccess
Important Notes
Form objects do not connect directly to the database like ActiveRecord models.
They are great for complex forms that touch multiple models or need custom validation.
Remember to test form objects separately from your database models.
Summary
Form objects keep form logic separate from database models.
They use ActiveModel::Model to behave like models without a table.
They help manage complex forms and validations cleanly.