DEV Community

Andy Huynh
Andy Huynh

Posted on

handy Ruby methods #4 - Hash#dig

cool diglet

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
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode

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)