author avatar

nived.hari

Thu Nov 28 2024

Form Objects in Rails
Form objects are a pattern that is used to encapsulate logic for managing and validating form data. They act as an intermediary between the view and the model layer, they simplify the handling of complex forms, particularly when working with complex forms that don't map to a single active record model.
Why use form objects?
In typical rails applications, forms are directly tied to active record models. This is ok when the forms are simple, but this can cause problem when complexity increases such as,
when forms interact with multiple models
In these kind of scenarios, we can encapsulate the corresponding logic into a single class which acts like an active record model which is easier to maintain.

Example form object
app/forms/route_request_form.rb


class UserProfileForm
  include ActiveModel::Model

 # Attributes accessible for the form object.
  attr_accessor :user_name, :email, :profile_bio, :profile_age

  validates :user_name, :email, presence: true
  validates :profile_age, numericality: { only_integer: true, greater_than: 0 }

  def save
    return false unless valid?
    
    #a single transaction for multiple operations
    ActiveRecord::Base.transaction do
      user = User.create!(name: user_name, email: email)
      user.create_profile!(bio: profile_bio, age: profile_age)
    end

    true # Return true if all operations succeed.
  rescue ActiveRecord::RecordInvalid
    false # Return false if the save process fails.
  end
end


Using it in controller


class UsersController < ApplicationController
  def new
    @form = UserProfileForm.new
  end

  def create
    @form = UserProfileForm.new(user_profile_form_params)

    if @form.save
      redirect_to root_path, notice: "User created successfully!"
    else
      render :new, status: :unprocessable_entity
    end
  end

  private

  def user_profile_form_params
    params.require(:user_profile_form).permit(:user_name, :email, :profile_bio, :profile_age)
  end
end




#ruby_on_rails #form_objects