actionpack 4.2.11.3 → 5.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (125) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +379 -462
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/abstract_controller.rb +0 -2
  6. data/lib/abstract_controller/base.rb +17 -32
  7. data/lib/abstract_controller/callbacks.rb +52 -19
  8. data/lib/abstract_controller/collector.rb +4 -9
  9. data/lib/abstract_controller/helpers.rb +2 -2
  10. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  11. data/lib/abstract_controller/rendering.rb +27 -22
  12. data/lib/abstract_controller/translation.rb +8 -7
  13. data/lib/action_controller.rb +4 -3
  14. data/lib/action_controller/api.rb +146 -0
  15. data/lib/action_controller/base.rb +6 -10
  16. data/lib/action_controller/caching.rb +1 -3
  17. data/lib/action_controller/caching/fragments.rb +48 -3
  18. data/lib/action_controller/form_builder.rb +48 -0
  19. data/lib/action_controller/log_subscriber.rb +1 -10
  20. data/lib/action_controller/metal.rb +89 -62
  21. data/lib/action_controller/metal/basic_implicit_render.rb +11 -0
  22. data/lib/action_controller/metal/conditional_get.rb +65 -24
  23. data/lib/action_controller/metal/cookies.rb +0 -2
  24. data/lib/action_controller/metal/data_streaming.rb +2 -22
  25. data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
  26. data/lib/action_controller/metal/exceptions.rb +11 -6
  27. data/lib/action_controller/metal/force_ssl.rb +6 -6
  28. data/lib/action_controller/metal/head.rb +14 -7
  29. data/lib/action_controller/metal/helpers.rb +9 -5
  30. data/lib/action_controller/metal/http_authentication.rb +37 -38
  31. data/lib/action_controller/metal/implicit_render.rb +23 -6
  32. data/lib/action_controller/metal/instrumentation.rb +0 -1
  33. data/lib/action_controller/metal/live.rb +17 -55
  34. data/lib/action_controller/metal/mime_responds.rb +17 -37
  35. data/lib/action_controller/metal/params_wrapper.rb +8 -8
  36. data/lib/action_controller/metal/redirecting.rb +32 -9
  37. data/lib/action_controller/metal/renderers.rb +10 -8
  38. data/lib/action_controller/metal/rendering.rb +38 -6
  39. data/lib/action_controller/metal/request_forgery_protection.rb +67 -35
  40. data/lib/action_controller/metal/rescue.rb +2 -4
  41. data/lib/action_controller/metal/streaming.rb +4 -4
  42. data/lib/action_controller/metal/strong_parameters.rb +231 -78
  43. data/lib/action_controller/metal/testing.rb +1 -12
  44. data/lib/action_controller/metal/url_for.rb +12 -5
  45. data/lib/action_controller/renderer.rb +111 -0
  46. data/lib/action_controller/template_assertions.rb +9 -0
  47. data/lib/action_controller/test_case.rb +267 -363
  48. data/lib/action_dispatch.rb +2 -1
  49. data/lib/action_dispatch/http/cache.rb +23 -26
  50. data/lib/action_dispatch/http/filter_parameters.rb +6 -8
  51. data/lib/action_dispatch/http/filter_redirect.rb +7 -8
  52. data/lib/action_dispatch/http/headers.rb +28 -11
  53. data/lib/action_dispatch/http/mime_negotiation.rb +40 -26
  54. data/lib/action_dispatch/http/mime_type.rb +92 -61
  55. data/lib/action_dispatch/http/mime_types.rb +1 -4
  56. data/lib/action_dispatch/http/parameter_filter.rb +18 -8
  57. data/lib/action_dispatch/http/parameters.rb +45 -41
  58. data/lib/action_dispatch/http/request.rb +146 -82
  59. data/lib/action_dispatch/http/response.rb +180 -99
  60. data/lib/action_dispatch/http/url.rb +117 -8
  61. data/lib/action_dispatch/journey/formatter.rb +34 -28
  62. data/lib/action_dispatch/journey/gtg/transition_table.rb +1 -1
  63. data/lib/action_dispatch/journey/nfa/dot.rb +0 -2
  64. data/lib/action_dispatch/journey/nfa/transition_table.rb +1 -46
  65. data/lib/action_dispatch/journey/nodes/node.rb +14 -4
  66. data/lib/action_dispatch/journey/parser_extras.rb +4 -0
  67. data/lib/action_dispatch/journey/path/pattern.rb +37 -41
  68. data/lib/action_dispatch/journey/route.rb +71 -17
  69. data/lib/action_dispatch/journey/router.rb +5 -6
  70. data/lib/action_dispatch/journey/router/utils.rb +5 -5
  71. data/lib/action_dispatch/journey/routes.rb +14 -15
  72. data/lib/action_dispatch/journey/visitors.rb +86 -43
  73. data/lib/action_dispatch/middleware/cookies.rb +184 -135
  74. data/lib/action_dispatch/middleware/debug_exceptions.rb +115 -45
  75. data/lib/action_dispatch/middleware/exception_wrapper.rb +21 -20
  76. data/lib/action_dispatch/middleware/flash.rb +61 -45
  77. data/lib/action_dispatch/middleware/load_interlock.rb +21 -0
  78. data/lib/action_dispatch/middleware/params_parser.rb +30 -46
  79. data/lib/action_dispatch/middleware/public_exceptions.rb +2 -2
  80. data/lib/action_dispatch/middleware/reloader.rb +2 -4
  81. data/lib/action_dispatch/middleware/remote_ip.rb +29 -19
  82. data/lib/action_dispatch/middleware/request_id.rb +11 -6
  83. data/lib/action_dispatch/middleware/session/abstract_store.rb +23 -11
  84. data/lib/action_dispatch/middleware/session/cache_store.rb +9 -6
  85. data/lib/action_dispatch/middleware/session/cookie_store.rb +29 -23
  86. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +4 -0
  87. data/lib/action_dispatch/middleware/show_exceptions.rb +11 -9
  88. data/lib/action_dispatch/middleware/ssl.rb +93 -36
  89. data/lib/action_dispatch/middleware/stack.rb +43 -48
  90. data/lib/action_dispatch/middleware/static.rb +52 -40
  91. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +2 -14
  92. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +0 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +1 -1
  95. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  96. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  97. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +59 -63
  98. data/lib/action_dispatch/railtie.rb +0 -2
  99. data/lib/action_dispatch/request/session.rb +66 -34
  100. data/lib/action_dispatch/request/utils.rb +51 -19
  101. data/lib/action_dispatch/routing.rb +3 -8
  102. data/lib/action_dispatch/routing/inspector.rb +6 -30
  103. data/lib/action_dispatch/routing/mapper.rb +447 -322
  104. data/lib/action_dispatch/routing/polymorphic_routes.rb +8 -14
  105. data/lib/action_dispatch/routing/redirection.rb +3 -3
  106. data/lib/action_dispatch/routing/route_set.rb +124 -227
  107. data/lib/action_dispatch/routing/url_for.rb +27 -10
  108. data/lib/action_dispatch/testing/assertions.rb +1 -1
  109. data/lib/action_dispatch/testing/assertions/response.rb +27 -9
  110. data/lib/action_dispatch/testing/assertions/routing.rb +9 -9
  111. data/lib/action_dispatch/testing/integration.rb +237 -76
  112. data/lib/action_dispatch/testing/test_process.rb +5 -5
  113. data/lib/action_dispatch/testing/test_request.rb +12 -21
  114. data/lib/action_dispatch/testing/test_response.rb +1 -4
  115. data/lib/action_pack.rb +1 -1
  116. data/lib/action_pack/gem_version.rb +4 -4
  117. metadata +26 -25
  118. data/lib/action_controller/metal/hide_actions.rb +0 -40
  119. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  120. data/lib/action_controller/middleware.rb +0 -39
  121. data/lib/action_controller/model_naming.rb +0 -12
  122. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  123. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  124. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  125. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -5,20 +5,8 @@
5
5
  <pre id="blame_trace" <%='style="display:none"' if hide %>><code><%= @exception.describe_blame %></code></pre>
6
6
  <% end %>
7
7
 
8
- <%
9
- clean_params = @request.filtered_parameters.clone
10
- clean_params.delete("action")
11
- clean_params.delete("controller")
12
-
13
- request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
14
-
15
- def debug_hash(object)
16
- object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
17
- end unless self.class.method_defined?(:debug_hash)
18
- %>
19
-
20
8
  <h2 style="margin-top: 30px">Request</h2>
21
- <p><b>Parameters</b>:</p> <pre><%= request_dump %></pre>
9
+ <p><b>Parameters</b>:</p> <pre><%= debug_params(@request.filtered_parameters) %></pre>
22
10
 
23
11
  <div class="details">
24
12
  <div class="summary"><a href="#" onclick="return toggleSessionDump()">Toggle session dump</a></div>
@@ -31,4 +19,4 @@
31
19
  </div>
32
20
 
33
21
  <h2 style="margin-top: 30px">Response</h2>
34
- <p><b>Headers</b>:</p> <pre><%= defined?(@response) ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre>
22
+ <p><b>Headers</b>:</p> <pre><%= debug_headers(defined?(@response) ? @response.headers : {}) %></pre>
@@ -0,0 +1,8 @@
1
+ <% @source_extracts.first(3).each do |source_extract| %>
2
+ <% if source_extract[:code] %>
3
+ Extracted source (around line #<%= source_extract[:line_number] %>):
4
+
5
+ <% source_extract[:code].each do |line, source| -%>
6
+ <%= line == source_extract[:line_number] ? "*#{line}" : "##{line}" -%> <%= source -%><% end -%>
7
+ <% end %>
8
+ <% end %>
@@ -1,6 +1,6 @@
1
1
  <header>
2
2
  <h1>
3
- <%= @exception.original_exception.class.to_s %> in
3
+ <%= @exception.cause.class.to_s %> in
4
4
  <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
5
5
  </h1>
6
6
  </header>
@@ -1,4 +1,4 @@
1
- <%= @exception.original_exception.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
1
+ <%= @exception.cause.class.to_s %> in <%= @request.parameters["controller"].camelize if @request.parameters["controller"] %>#<%= @request.parameters["action"] %>
2
2
 
3
3
  Showing <%= @exception.file_name %> where line #<%= @exception.line_number %> raised:
4
4
  <%= @exception.message %>
@@ -4,13 +4,13 @@
4
4
  <%= route[:name] %><span class='helper'>_path</span>
5
5
  <% end %>
6
6
  </td>
7
- <td data-route-verb='<%= route[:verb] %>'>
7
+ <td>
8
8
  <%= route[:verb] %>
9
9
  </td>
10
- <td data-route-path='<%= route[:path] %>' data-regexp='<%= route[:regexp] %>'>
10
+ <td data-route-path='<%= route[:path] %>'>
11
11
  <%= route[:path] %>
12
12
  </td>
13
- <td data-route-reqs='<%= route[:reqs] %>'>
14
- <%= route[:reqs] %>
13
+ <td>
14
+ <%=simple_format route[:reqs] %>
15
15
  </td>
16
16
  </tr>
@@ -81,92 +81,87 @@
81
81
  </table>
82
82
 
83
83
  <script type='text/javascript'>
84
- // Iterates each element through a function
85
- function each(elems, func) {
86
- if (!elems instanceof Array) { elems = [elems]; }
87
- for (var i = 0, len = elems.length; i < len; i++) {
88
- func(elems[i]);
89
- }
90
- }
91
-
92
- // Sets innerHTML for an element
93
- function setContent(elem, text) {
94
- elem.innerHTML = text;
95
- }
84
+ // support forEarch iterator on NodeList
85
+ NodeList.prototype.forEach = Array.prototype.forEach;
96
86
 
97
87
  // Enables path search functionality
98
88
  function setupMatchPaths() {
99
- // Check if the user input (sanitized as a path) matches the regexp data attribute
100
- function checkExactMatch(section, elem, value) {
101
- var string = sanitizePath(value),
102
- regexp = elem.getAttribute("data-regexp");
103
-
104
- showMatch(string, regexp, section, elem);
89
+ // Check if there are any matched results in a section
90
+ function checkNoMatch(section, noMatchText) {
91
+ if (section.children.length <= 1) {
92
+ section.innerHTML += noMatchText;
93
+ }
105
94
  }
106
95
 
107
- // Check if the route path data attribute contains the user input
108
- function checkFuzzyMatch(section, elem, value) {
109
- var string = elem.getAttribute("data-route-path"),
110
- regexp = value;
111
-
112
- showMatch(string, regexp, section, elem);
96
+ // get JSON from url and invoke callback with result
97
+ function getJSON(url, success) {
98
+ var xhr = new XMLHttpRequest();
99
+ xhr.open('GET', url);
100
+ xhr.onload = function() {
101
+ if (this.status == 200)
102
+ success(JSON.parse(this.response));
103
+ };
104
+ xhr.send();
113
105
  }
114
106
 
115
- // Display the parent <tr> element in the appropriate section when there's a match
116
- function showMatch(string, regexp, section, elem) {
117
- if(string.match(RegExp(regexp))) {
118
- section.appendChild(elem.parentNode.cloneNode(true));
107
+ function delayedKeyup(input, callback) {
108
+ var timeout;
109
+ input.onkeyup = function(){
110
+ if (timeout) clearTimeout(timeout);
111
+ timeout = setTimeout(callback, 300);
119
112
  }
120
113
  }
121
114
 
122
- // Check if there are any matched results in a section
123
- function checkNoMatch(section, defaultText, noMatchText) {
124
- if (section.innerHTML === defaultText) {
125
- setContent(section, defaultText + noMatchText);
126
- }
127
- }
128
-
129
- // Ensure path always starts with a slash "/" and remove params or fragments
115
+ // remove params or fragments
130
116
  function sanitizePath(path) {
131
- var path = path.charAt(0) == '/' ? path : "/" + path;
132
- return path.replace(/\#.*|\?.*/, '');
117
+ return path.replace(/[#?].*/, '');
133
118
  }
134
119
 
135
- var regexpElems = document.querySelectorAll('#route_table [data-regexp]'),
136
- searchElem = document.querySelector('#search'),
137
- exactMatches = document.querySelector('#exact_matches'),
138
- fuzzyMatches = document.querySelector('#fuzzy_matches');
120
+ var pathElements = document.querySelectorAll('#route_table [data-route-path]'),
121
+ searchElem = document.querySelector('#search'),
122
+ exactSection = document.querySelector('#exact_matches'),
123
+ fuzzySection = document.querySelector('#fuzzy_matches');
139
124
 
140
125
  // Remove matches when no search value is present
141
126
  searchElem.onblur = function(e) {
142
127
  if (searchElem.value === "") {
143
- setContent(exactMatches, "");
144
- setContent(fuzzyMatches, "");
128
+ exactSection.innerHTML = "";
129
+ fuzzySection.innerHTML = "";
145
130
  }
146
131
  }
147
132
 
148
133
  // On key press perform a search for matching paths
149
- searchElem.onkeyup = function(e){
150
- var userInput = searchElem.value,
151
- defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + escape(sanitizePath(userInput)) +'):</th></tr>',
152
- defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + escape(userInput) +'):</th></tr>',
134
+ delayedKeyup(searchElem, function() {
135
+ var path = sanitizePath(searchElem.value),
136
+ defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + path +'):</th></tr>',
137
+ defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + path +'):</th></tr>',
153
138
  noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>',
154
139
  noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>';
155
140
 
156
- // Clear out results section
157
- setContent(exactMatches, defaultExactMatch);
158
- setContent(fuzzyMatches, defaultFuzzyMatch);
141
+ if (!path)
142
+ return searchElem.onblur();
159
143
 
160
- // Display exact matches and fuzzy matches
161
- each(regexpElems, function(elem) {
162
- checkExactMatch(exactMatches, elem, userInput);
163
- checkFuzzyMatch(fuzzyMatches, elem, userInput);
164
- })
144
+ getJSON('/rails/info/routes?path=' + path, function(matches){
145
+ // Clear out results section
146
+ exactSection.innerHTML = defaultExactMatch;
147
+ fuzzySection.innerHTML = defaultFuzzyMatch;
165
148
 
166
- // Display 'No Matches' message when no matches are found
167
- checkNoMatch(exactMatches, defaultExactMatch, noExactMatch);
168
- checkNoMatch(fuzzyMatches, defaultFuzzyMatch, noFuzzyMatch);
169
- }
149
+ // Display exact matches and fuzzy matches
150
+ pathElements.forEach(function(elem) {
151
+ var elemPath = elem.getAttribute('data-route-path');
152
+
153
+ if (matches['exact'].indexOf(elemPath) != -1)
154
+ exactSection.appendChild(elem.parentNode.cloneNode(true));
155
+
156
+ if (matches['fuzzy'].indexOf(elemPath) != -1)
157
+ fuzzySection.appendChild(elem.parentNode.cloneNode(true));
158
+ })
159
+
160
+ // Display 'No Matches' message when no matches are found
161
+ checkNoMatch(exactSection, noExactMatch);
162
+ checkNoMatch(fuzzySection, noFuzzyMatch);
163
+ })
164
+ })
170
165
  }
171
166
 
172
167
  // Enables functionality to toggle between `_path` and `_url` helper suffixes
@@ -174,19 +169,20 @@
174
169
 
175
170
  // Sets content for each element
176
171
  function setValOn(elems, val) {
177
- each(elems, function(elem) {
178
- setContent(elem, val);
172
+ elems.forEach(function(elem) {
173
+ elem.innerHTML = val;
179
174
  });
180
175
  }
181
176
 
182
177
  // Sets onClick event for each element
183
178
  function onClick(elems, func) {
184
- each(elems, function(elem) {
179
+ elems.forEach(function(elem) {
185
180
  elem.onclick = func;
186
181
  });
187
182
  }
188
183
 
189
184
  var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
185
+
190
186
  onClick(toggleLinks, function(){
191
187
  var helperTxt = this.getAttribute("data-route-helper"),
192
188
  helperElems = document.querySelectorAll('[data-route-name] span.helper');
@@ -40,8 +40,6 @@ module ActionDispatch
40
40
  ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
41
41
 
42
42
  ActionDispatch.test_app = app
43
-
44
- ActionDispatch::Routing::RouteSet.relative_url_root = app.config.relative_url_root
45
43
  end
46
44
  end
47
45
  end
@@ -1,56 +1,56 @@
1
1
  require 'rack/session/abstract/id'
2
2
 
3
3
  module ActionDispatch
4
- class Request < Rack::Request
4
+ class Request
5
5
  # Session is responsible for lazily loading the session from store.
6
6
  class Session # :nodoc:
7
- ENV_SESSION_KEY = Rack::Session::Abstract::ENV_SESSION_KEY # :nodoc:
8
- ENV_SESSION_OPTIONS_KEY = Rack::Session::Abstract::ENV_SESSION_OPTIONS_KEY # :nodoc:
7
+ ENV_SESSION_KEY = Rack::RACK_SESSION # :nodoc:
8
+ ENV_SESSION_OPTIONS_KEY = Rack::RACK_SESSION_OPTIONS # :nodoc:
9
9
 
10
10
  # Singleton object used to determine if an optional param wasn't specified
11
11
  Unspecified = Object.new
12
-
13
- def self.create(store, env, default_options)
14
- session_was = find env
15
- session = Request::Session.new(store, env)
12
+
13
+ # Creates a session hash, merging the properties of the previous session if any
14
+ def self.create(store, req, default_options)
15
+ session_was = find req
16
+ session = Request::Session.new(store, req)
16
17
  session.merge! session_was if session_was
17
18
 
18
- set(env, session)
19
- Options.set(env, Request::Session::Options.new(store, env, default_options))
19
+ set(req, session)
20
+ Options.set(req, Request::Session::Options.new(store, default_options))
20
21
  session
21
22
  end
22
23
 
23
- def self.find(env)
24
- env[ENV_SESSION_KEY]
24
+ def self.find(req)
25
+ req.get_header ENV_SESSION_KEY
25
26
  end
26
27
 
27
- def self.set(env, session)
28
- env[ENV_SESSION_KEY] = session
28
+ def self.set(req, session)
29
+ req.set_header ENV_SESSION_KEY, session
29
30
  end
30
31
 
31
32
  class Options #:nodoc:
32
- def self.set(env, options)
33
- env[ENV_SESSION_OPTIONS_KEY] = options
33
+ def self.set(req, options)
34
+ req.set_header ENV_SESSION_OPTIONS_KEY, options
34
35
  end
35
36
 
36
- def self.find(env)
37
- env[ENV_SESSION_OPTIONS_KEY]
37
+ def self.find(req)
38
+ req.get_header ENV_SESSION_OPTIONS_KEY
38
39
  end
39
40
 
40
- def initialize(by, env, default_options)
41
+ def initialize(by, default_options)
41
42
  @by = by
42
- @env = env
43
43
  @delegate = default_options.dup
44
44
  end
45
45
 
46
46
  def [](key)
47
- if key == :id
48
- @delegate.fetch(key) {
49
- @delegate[:id] = @by.send(:extract_session_id, @env)
50
- }
51
- else
52
- @delegate[key]
53
- end
47
+ @delegate[key]
48
+ end
49
+
50
+ def id(req)
51
+ @delegate.fetch(:id) {
52
+ @by.send(:extract_session_id, req)
53
+ }
54
54
  end
55
55
 
56
56
  def []=(k,v); @delegate[k] = v; end
@@ -58,38 +58,40 @@ module ActionDispatch
58
58
  def values_at(*args); @delegate.values_at(*args); end
59
59
  end
60
60
 
61
- def initialize(by, env)
61
+ def initialize(by, req)
62
62
  @by = by
63
- @env = env
63
+ @req = req
64
64
  @delegate = {}
65
65
  @loaded = false
66
66
  @exists = nil # we haven't checked yet
67
67
  end
68
68
 
69
69
  def id
70
- options[:id]
70
+ options.id(@req)
71
71
  end
72
72
 
73
73
  def options
74
- Options.find @env
74
+ Options.find @req
75
75
  end
76
76
 
77
77
  def destroy
78
78
  clear
79
79
  options = self.options || {}
80
- new_sid = @by.send(:destroy_session, @env, options[:id], options)
81
- options[:id] = new_sid # Reset session id with a new value or nil
80
+ @by.send(:delete_session, @req, options.id(@req), options)
82
81
 
83
82
  # Load the new sid to be written with the response
84
83
  @loaded = false
85
84
  load_for_write!
86
85
  end
87
86
 
87
+ # Returns value of the key stored in the session or
88
+ # nil if the given key is not found in the session.
88
89
  def [](key)
89
90
  load_for_read!
90
91
  @delegate[key.to_s]
91
92
  end
92
93
 
94
+ # Returns true if the session has the given key or false.
93
95
  def has_key?(key)
94
96
  load_for_read!
95
97
  @delegate.key?(key.to_s)
@@ -97,39 +99,69 @@ module ActionDispatch
97
99
  alias :key? :has_key?
98
100
  alias :include? :has_key?
99
101
 
102
+ # Returns keys of the session as Array.
100
103
  def keys
101
104
  @delegate.keys
102
105
  end
103
106
 
107
+ # Returns values of the session as Array.
104
108
  def values
105
109
  @delegate.values
106
110
  end
107
111
 
112
+ # Writes given value to given key of the session.
108
113
  def []=(key, value)
109
114
  load_for_write!
110
115
  @delegate[key.to_s] = value
111
116
  end
112
117
 
118
+ # Clears the session.
113
119
  def clear
114
120
  load_for_write!
115
121
  @delegate.clear
116
122
  end
117
123
 
124
+ # Returns the session as Hash.
118
125
  def to_hash
119
126
  load_for_read!
120
127
  @delegate.dup.delete_if { |_,v| v.nil? }
121
128
  end
122
129
 
130
+ # Updates the session with given Hash.
131
+ #
132
+ # session.to_hash
133
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2"}
134
+ #
135
+ # session.update({ "foo" => "bar" })
136
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
137
+ #
138
+ # session.to_hash
139
+ # # => {"session_id"=>"e29b9ea315edf98aad94cc78c34cc9b2", "foo" => "bar"}
123
140
  def update(hash)
124
141
  load_for_write!
125
142
  @delegate.update stringify_keys(hash)
126
143
  end
127
144
 
145
+ # Deletes given key from the session.
128
146
  def delete(key)
129
147
  load_for_write!
130
148
  @delegate.delete key.to_s
131
149
  end
132
150
 
151
+ # Returns value of given key from the session, or raises +KeyError+
152
+ # if can't find given key in case of not setted dafault value.
153
+ # Returns default value if specified.
154
+ #
155
+ # session.fetch(:foo)
156
+ # # => KeyError: key not found: "foo"
157
+ #
158
+ # session.fetch(:foo, :bar)
159
+ # # => :bar
160
+ #
161
+ # session.fetch(:foo) do
162
+ # :bar
163
+ # end
164
+ # # => :bar
133
165
  def fetch(key, default=Unspecified, &block)
134
166
  load_for_read!
135
167
  if default == Unspecified
@@ -149,7 +181,7 @@ module ActionDispatch
149
181
 
150
182
  def exists?
151
183
  return @exists unless @exists.nil?
152
- @exists = @by.send(:session_exists?, @env)
184
+ @exists = @by.send(:session_exists?, @req)
153
185
  end
154
186
 
155
187
  def loaded?
@@ -177,7 +209,7 @@ module ActionDispatch
177
209
  end
178
210
 
179
211
  def load!
180
- id, session = @by.load_session @env
212
+ id, session = @by.load_session @req
181
213
  options[:id] = id
182
214
  @delegate.replace(stringify_keys(session))
183
215
  @loaded = true