diff options
author | claudiob <claudiob@gmail.com> | 2016-02-24 10:51:30 -0800 |
---|---|---|
committer | sinsoku <sinsoku.listy@gmail.com> | 2018-04-04 16:20:16 +0900 |
commit | 398267b14220c6659d6b1f8fdebf36ce7f8d58c9 (patch) | |
tree | 82118424dab2a3d1b85d643afe52e6994d8d722f /actionpack | |
parent | a07d0680787ced3c04b362fa7a238c918211ac70 (diff) | |
download | rails-398267b14220c6659d6b1f8fdebf36ce7f8d58c9.tar.gz rails-398267b14220c6659d6b1f8fdebf36ce7f8d58c9.tar.bz2 rails-398267b14220c6659d6b1f8fdebf36ce7f8d58c9.zip |
Add #dig to ActionDispatch::Request::Session
### Summary
The `session` object is not a real Hash but responds to many methods of Hash
such as `[]`, `[]`, `fetch`, `has_key?`.
Since Ruby 2.3, Hash also supports a `dig` method.
This commit adds a `dig` method to `ActionDispatch::Request::Session` with the
same behavior as `Hash#dig`.
This is useful if you store a hash in your session, such as:
```ruby
session[:user] = { id: 1, avatar_url: "http://example.org/nyancat.jpg" }
```
Then you can shorten your code from `session[:user][:avatar_url]` to `session.dig :user, :avatar_url`.
### Other Information
I cherry-picked a commit from https://github.com/rails/rails/pull/23864, and modify a bit.
The changes are below:
* Converts only the first key to a string adjust to the `fetch` method.
* Fixes a test case because we cannot use the indifferent access since ee5b621e2f8fde380ea4bc75b0b9d6f98499f511.
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/action_dispatch/request/session.rb | 8 | ||||
-rw-r--r-- | actionpack/test/dispatch/request/session_test.rb | 12 |
2 files changed, 20 insertions, 0 deletions
diff --git a/actionpack/lib/action_dispatch/request/session.rb b/actionpack/lib/action_dispatch/request/session.rb index 000847e193..2ff651fc31 100644 --- a/actionpack/lib/action_dispatch/request/session.rb +++ b/actionpack/lib/action_dispatch/request/session.rb @@ -93,6 +93,14 @@ module ActionDispatch @delegate[key.to_s] end + # Returns the nested value specified by the sequence of key, returning + # nil if any intermediate step is nil. + def dig(*keys) + load_for_read! + keys = keys.map.with_index { |key, i| i.zero? ? key.to_s : key } + @delegate.dig(*keys) + end + # Returns true if the session has the given key or false. def has_key?(key) load_for_read! diff --git a/actionpack/test/dispatch/request/session_test.rb b/actionpack/test/dispatch/request/session_test.rb index bf5a74e694..74da2fe7d3 100644 --- a/actionpack/test/dispatch/request/session_test.rb +++ b/actionpack/test/dispatch/request/session_test.rb @@ -118,6 +118,18 @@ module ActionDispatch end end + def test_dig + session = Session.create(store, req, {}) + session["one"] = { "two" => "3" } + + assert_equal "3", session.dig("one", "two") + assert_equal "3", session.dig(:one, "two") + + assert_nil session.dig("three", "two") + assert_nil session.dig("one", "three") + assert_nil session.dig("one", :two) + end + private def store Class.new { |