Before Ruby 2.3
class AutomationController < ActionController::Base
def automation_trigger_type
params.fetch(:automation_rule, {}).fetch(:trigger_attributes, {}).fetch(:type).tap do |trigger_type|
raise "unknown type" unless trigger_type.blank?
end
end
end
After Ruby 2.3
class AutomationController < ActionController::Base
def automation_trigger_type
params.dig(:automation_rule, :trigger_attributes, :type).tap do |trigger_type|
raise "unknown type" unless trigger_type.blank?
end
end
end
Life after Ruby 2.3 breathes an elegant expression to drill into a hash.
In the first example, Hash#fetch is invoked multiple times. It drills two levels into a nested params hash :automation_rule. A default is included to avoid the dreaded NoMethodErrors on nil error.
This approach is verbose to say the least. It's painful to look at in the eyes of a Ruby dev.
The latter example is more terse. First, Hash#dig checks if the param key :automation_rule exists. If there's a key, it digs down a nested level and looks for the key :trigger_attributes. And so on..
Anywhere Hash#dig does not find a key, it returns nil in lieu of an error.
I notice Hash#dig used in Rails controllers. Digging into controller params is commonplace as an app builds in complexity. It's also prevalent digging through an API response where the returned payload is a deeply nested JSON object.
Hash#dig is a staple to write battle-tested code.

Top comments (0)