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.