Organized kitchen drawer with dishes and cups neatly arranged

Orgalux

Group Repeated Options with with_options

When multiple validations share the same if: condition, or multiple callbacks share the same only: constraint, you end up repeating yourself. with_options groups them together.

Instead of…

…repeating conditions across multiple validations:

class Article < ApplicationRecord
  validates :title, presence: true, if: :published?
  validates :body, length: { minimum: 100 }, if: :published?
  validates :author, presence: true, if: :published?
end

Use…

…the with_options method to group common configurations:

class Article < ApplicationRecord
  with_options if: :published? do
    validates :title, presence: true
    validates :body, length: { minimum: 100 }
    validates :author, presence: true
  end
end

Works well in controllers too:

class AdminController < ApplicationController
  with_options only: [:edit, :update] do
    before_action :require_admin
    before_action :set_audit_trail
  end
end

And associations:

class User < ApplicationRecord
  with_options dependent: :destroy do
    has_many :posts
    has_many :comments
    has_many :likes
  end
end

Why?

with_options merges the given options into every method call inside the block. In the validation example, if: :published? gets added to each validates call automatically.

This syntax groups related configuration visually—it’s immediately clear these rules only apply to published articles. If you have to change the condition; it is only once, not three times.

This also works in routes.rb too:

with_options controller: "admin/reports" do
  get "daily", action: :daily
  get "weekly", action: :weekly
  get "monthly", action: :monthly
end

See the with_options documentation for details.

Why not?

With only two items, the block adds more lines than it saves. Three or more is where with_options starts to pay off.

Nesting multiple with_options blocks gets hard to follow. If you find yourself nesting, reconsider.

Published on March 9th, 2026