Rails 6 adds dig method to ActionDispatch::Request::Session

1 minute read

The Rails session object supports many hash methods. Ruby 2.3 introduced dig method to Hash , for safe hash traversal. Rails 6 brings dig method to ActionDispatch::Request::Session similar to Hash#dig .

This is useful if we have a want to access data or nested hashes in our session.

Before Rails 6

Lets take a look of this user attributes information, for current user stored as session information:

session [ :user ] = { id: 1 , name: 'John Doe' , gender: 'male' , notifications: [{ kind: 'cancellation' , email: true , text: false }, { kind: 'reminder' , email: true , text: true }]}

We can access this individual piece of information by hash access like so:

# Retrieving user's name from session session [ :user ][ :name ] #=> "John Doe" # Retrieving kind from notifications at a particular index session [ :user ][ :notifications ][ 1 ][ :kind ] #=> "reminder"

While retrieving the value if any of the key is missing, it throws a NoMethodError :

# Retrieving user's phone number ext # Phone key does not exist in hash session [ :user ][ :phone ][ :ext ] *** NoMethodError Exception : undefined method '[]' for nil :NilClass # Retrieving kind from notifications at index 2 # There are no notifications at index 2 session [ :user ][ :notifications ][ 2 ][ :kind ] *** NoMethodError Exception : undefined method '[]' for nil :NilClass

To handle this error, we need to add individual key presence checks.

# Adding phone key presence check session [ :user ][ :phone ] ? session [: user ][ :phone ][ :ext ] : nil #=> nil

This can get quite descriptive and repetitive.

With Rails 6

With Rails 6, we can now make use of dig method instead to access this information:

# Retrieving user's name from session session . dig :user , :name #=> "John Doe" # Retrieving kind from notifications at a particular index session . dig :user , :notifications , 1 , :kind #=> "reminder"

dig returns nil if any key is missing. This takes care of handling any nil values in nested hash accesses and returns nil .

# From out examples before session . dig :user , :phone , :ext #=> nil session . dig :user , :notifications , 2 , :kind #=> nil

This allows us for simpler, safer access, of session objects.