aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorclaudiob <claudiob@gmail.com>2016-02-24 10:51:30 -0800
committersinsoku <sinsoku.listy@gmail.com>2018-04-04 16:20:16 +0900
commit398267b14220c6659d6b1f8fdebf36ce7f8d58c9 (patch)
tree82118424dab2a3d1b85d643afe52e6994d8d722f /actionpack
parenta07d0680787ced3c04b362fa7a238c918211ac70 (diff)
downloadrails-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.rb8
-rw-r--r--actionpack/test/dispatch/request/session_test.rb12
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 {