with_options in Rails
Active Support in Rails adds a with_option
method to the Object
(i.e., it’s available everywhere).
It yields a proxy object, which adds given options to each method call:
def log(arg, **kwargs)
puts(arg: arg, kwargs: kwargs)
end
> with_options a: 123 do |with_a|
> with_a.log(:called_with_a)
> log(:called_without_a)
> with_a.log(:called_with_a_and_b, b: 456)
> with_a.log(:called_with_overwritten_a, a: 789)
> end
{:arg=>:called_with_a, :kwargs=>{:a=>123}}
{:arg=>:called_without_a, :kwargs=>{}}
{:arg=>:called_with_a_and_b, :kwargs=>{:a=>123, :b=>456}}
{:arg=>:called_with_overwritten_a, :kwargs=>{:a=>789}}
You can use it to group multiple similar calls or to avoid repetition.
E.g., if you need to call I18n multiple times in a place that does not support inferring the scope:
I18n.with_options(scope: 'active_admin.orders.edit.details') do |i18n|
panel i18n.t('header', order_number: order_number) do
...
end
end
That way, each call to i18n.t
will have the correct scope
option without you having to repeat it over and over.
Another use case is to group conditional ActiveModel validations:
class EventForm < ApplicationRecord
with_options if: :teams_enabled? do |teams|
teams.validates :team_max, presence: true
teams.validates :team_descripion, length: { maximum: 500 }
end
end
Tweet