actionpack 4.2.0 → 4.2.1.rc1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +84 -0
- data/lib/action_controller/metal.rb +1 -4
- data/lib/action_controller/metal/head.rb +3 -3
- data/lib/action_controller/metal/http_authentication.rb +2 -4
- data/lib/action_controller/metal/instrumentation.rb +7 -4
- data/lib/action_controller/metal/mime_responds.rb +0 -1
- data/lib/action_controller/metal/request_forgery_protection.rb +3 -1
- data/lib/action_controller/test_case.rb +4 -1
- data/lib/action_dispatch/http/cache.rb +4 -3
- data/lib/action_dispatch/http/parameter_filter.rb +1 -1
- data/lib/action_dispatch/journey/router.rb +1 -0
- data/lib/action_dispatch/routing/mapper.rb +1 -1
- data/lib/action_dispatch/routing/polymorphic_routes.rb +6 -5
- data/lib/action_dispatch/routing/route_set.rb +31 -13
- data/lib/action_dispatch/testing/assertions/routing.rb +14 -8
- data/lib/action_dispatch/testing/test_response.rb +7 -0
- data/lib/action_pack/gem_version.rb +2 -2
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8aa8a907191a5cc8d89c7c009bbd20c3653143fc
|
4
|
+
data.tar.gz: 64001ae6a6ae6bf3a5c950e851c2b4ba436a254d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cbd61bf7f540adb6b243cd7eee590e77147ca4570770b9e63b2289e681682bcc1ecbf070b80123c40ea464b3d99c636d0f832d1a759f45cc34989e881918760
|
7
|
+
data.tar.gz: 168146b2bbebb6a666ac8cfaa1707e54092bdf0be8857e6577f35e12ed6f40855c29da329e750ed1ebb97899e87b01bfbf1540bac3f17fcf4a7df355c2d3a684
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,87 @@
|
|
1
|
+
* Non-string authenticity tokens do not raise NoMethodError when decoding
|
2
|
+
the masked token.
|
3
|
+
|
4
|
+
*Ville Lautanala*
|
5
|
+
|
6
|
+
* Explicitly ignored wildcard verbs when searching for HEAD routes before fallback
|
7
|
+
|
8
|
+
Fixes an issue where a mounted rack app at root would intercept the HEAD
|
9
|
+
request causing an incorrect behavior during the fall back to GET requests.
|
10
|
+
|
11
|
+
Example:
|
12
|
+
```ruby
|
13
|
+
draw do
|
14
|
+
get '/home' => 'test#index'
|
15
|
+
mount rack_app, at: '/'
|
16
|
+
end
|
17
|
+
head '/home'
|
18
|
+
assert_response :success
|
19
|
+
```
|
20
|
+
In this case, a HEAD request runs through the routes the first time and fails
|
21
|
+
to match anything. Then, it runs through the list with the fallback and matches
|
22
|
+
`get '/home'`. The original behavior would match the rack app in the first pass.
|
23
|
+
|
24
|
+
*Terence Sun*
|
25
|
+
|
26
|
+
* Preserve default format when generating URLs
|
27
|
+
|
28
|
+
Fixes an issue that would cause the format set in default_url_options to be
|
29
|
+
lost when generating URLs with fewer positional arguments than parameters in
|
30
|
+
the route definition.
|
31
|
+
|
32
|
+
Backport of #18627
|
33
|
+
|
34
|
+
*Tekin Suleyman*, *Dominic Baggott*
|
35
|
+
|
36
|
+
* Default headers, removed in controller actions, are no longer reapplied on
|
37
|
+
the test response.
|
38
|
+
|
39
|
+
*Jonas Baumann*
|
40
|
+
|
41
|
+
* Ensure `append_info_to_payload` is called even if an exception is raised.
|
42
|
+
|
43
|
+
Fixes an issue where when an exception is raised in the request the additonal
|
44
|
+
payload data is not available.
|
45
|
+
|
46
|
+
See:
|
47
|
+
* #14903
|
48
|
+
* https://github.com/roidrage/lograge/issues/37
|
49
|
+
|
50
|
+
*Dieter Komendera*, *Margus Pärt*
|
51
|
+
|
52
|
+
* Correctly rely on the response's status code to handle calls to `head`.
|
53
|
+
|
54
|
+
*Robin Dupret*
|
55
|
+
|
56
|
+
* Using `head` method returns empty response_body instead
|
57
|
+
of returning a single space " ".
|
58
|
+
|
59
|
+
The old behavior was added as a workaround for a bug in an early
|
60
|
+
version of Safari, where the HTTP headers are not returned correctly
|
61
|
+
if the response body has a 0-length. This is been fixed since and
|
62
|
+
the workaround is no longer necessary.
|
63
|
+
|
64
|
+
Fixes #18253.
|
65
|
+
|
66
|
+
*Prathamesh Sonpatki*
|
67
|
+
|
68
|
+
* Fix how polymorphic routes works with objects that implement `to_model`.
|
69
|
+
|
70
|
+
*Travis Grathwell*
|
71
|
+
|
72
|
+
* Fixed handling of positional url helper arguments when `format: false`.
|
73
|
+
|
74
|
+
Fixes #17819.
|
75
|
+
|
76
|
+
*Andrew White*, *Tatiana Soukiassian*
|
77
|
+
|
78
|
+
* Fixed usage of optional scopes in URL helpers.
|
79
|
+
|
80
|
+
*Alex Robbin*
|
81
|
+
|
82
|
+
|
83
|
+
## Rails 4.2.0 (December 20, 2014) ##
|
84
|
+
|
1
85
|
* Add `ActionController::Parameters#to_unsafe_h` to return an unfiltered
|
2
86
|
`Hash` representation of Parameters object. This is now a preferred way to
|
3
87
|
retrieve unfiltered parameters as we will stop inheriting `AC::Parameters`
|
@@ -173,6 +173,7 @@ module ActionController
|
|
173
173
|
def status
|
174
174
|
@_status
|
175
175
|
end
|
176
|
+
alias :response_code :status # :nodoc:
|
176
177
|
|
177
178
|
def status=(status)
|
178
179
|
@_status = Rack::Utils.status_code(status)
|
@@ -236,9 +237,5 @@ module ActionController
|
|
236
237
|
lambda { |env| new.dispatch(name, klass.new(env)) }
|
237
238
|
end
|
238
239
|
end
|
239
|
-
|
240
|
-
def _status_code #:nodoc:
|
241
|
-
@_status
|
242
|
-
end
|
243
240
|
end
|
244
241
|
end
|
@@ -29,14 +29,14 @@ module ActionController
|
|
29
29
|
self.status = status
|
30
30
|
self.location = url_for(location) if location
|
31
31
|
|
32
|
-
|
32
|
+
self.response_body = ""
|
33
|
+
|
34
|
+
if include_content?(self.response_code)
|
33
35
|
self.content_type = content_type || (Mime[formats.first] if formats)
|
34
36
|
self.response.charset = false if self.response
|
35
|
-
self.response_body = " "
|
36
37
|
else
|
37
38
|
headers.delete('Content-Type')
|
38
39
|
headers.delete('Content-Length')
|
39
|
-
self.response_body = ""
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -53,10 +53,8 @@ module ActionController
|
|
53
53
|
# In your integration tests, you can do something like this:
|
54
54
|
#
|
55
55
|
# def test_access_granted_from_xml
|
56
|
-
#
|
57
|
-
#
|
58
|
-
# 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
|
59
|
-
# )
|
56
|
+
# @request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(users(:dhh).name, users(:dhh).password)
|
57
|
+
# get "/notes/1.xml"
|
60
58
|
#
|
61
59
|
# assert_equal 200, status
|
62
60
|
# end
|
@@ -28,10 +28,13 @@ module ActionController
|
|
28
28
|
ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)
|
29
29
|
|
30
30
|
ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
begin
|
32
|
+
result = super
|
33
|
+
payload[:status] = response.status
|
34
|
+
result
|
35
|
+
ensure
|
36
|
+
append_info_to_payload(payload)
|
37
|
+
end
|
35
38
|
end
|
36
39
|
end
|
37
40
|
|
@@ -274,7 +274,9 @@ module ActionController #:nodoc:
|
|
274
274
|
# session token. Essentially the inverse of
|
275
275
|
# +masked_authenticity_token+.
|
276
276
|
def valid_authenticity_token?(session, encoded_masked_token)
|
277
|
-
|
277
|
+
if encoded_masked_token.nil? || encoded_masked_token.empty? || !encoded_masked_token.is_a?(String)
|
278
|
+
return false
|
279
|
+
end
|
278
280
|
|
279
281
|
begin
|
280
282
|
masked_token = Base64.strict_decode64(encoded_masked_token)
|
@@ -67,7 +67,10 @@ module ActionController
|
|
67
67
|
|
68
68
|
def reset_template_assertion
|
69
69
|
RENDER_TEMPLATE_INSTANCE_VARIABLES.each do |instance_variable|
|
70
|
-
|
70
|
+
ivar_name = "@_#{instance_variable}"
|
71
|
+
if instance_variable_defined?(ivar_name)
|
72
|
+
instance_variable_get(ivar_name).clear
|
73
|
+
end
|
71
74
|
end
|
72
75
|
end
|
73
76
|
|
@@ -69,17 +69,17 @@ module ActionDispatch
|
|
69
69
|
end
|
70
70
|
|
71
71
|
def date
|
72
|
-
if date_header = headers[
|
72
|
+
if date_header = headers[DATE]
|
73
73
|
Time.httpdate(date_header)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def date?
|
78
|
-
headers.include?(
|
78
|
+
headers.include?(DATE)
|
79
79
|
end
|
80
80
|
|
81
81
|
def date=(utc_time)
|
82
|
-
headers[
|
82
|
+
headers[DATE] = utc_time.httpdate
|
83
83
|
end
|
84
84
|
|
85
85
|
def etag=(etag)
|
@@ -89,6 +89,7 @@ module ActionDispatch
|
|
89
89
|
|
90
90
|
private
|
91
91
|
|
92
|
+
DATE = 'Date'.freeze
|
92
93
|
LAST_MODIFIED = "Last-Modified".freeze
|
93
94
|
ETAG = "ETag".freeze
|
94
95
|
CACHE_CONTROL = "Cache-Control".freeze
|
@@ -56,7 +56,7 @@ module ActionDispatch
|
|
56
56
|
elsif value.is_a?(Array)
|
57
57
|
value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
|
58
58
|
elsif blocks.any?
|
59
|
-
key = key.dup
|
59
|
+
key = key.dup if key.duplicable?
|
60
60
|
value = value.dup if value.duplicable?
|
61
61
|
blocks.each { |b| b.call(key, value) }
|
62
62
|
end
|
@@ -1520,7 +1520,7 @@ module ActionDispatch
|
|
1520
1520
|
end
|
1521
1521
|
|
1522
1522
|
def using_match_shorthand?(path, options)
|
1523
|
-
path && (options[:to] || options[:action]).nil? && path =~ %r{
|
1523
|
+
path && (options[:to] || options[:action]).nil? && path =~ %r{^/?[-\w]+/[-\w/]+$}
|
1524
1524
|
end
|
1525
1525
|
|
1526
1526
|
def decomposed_match(path, options) # :nodoc:
|
@@ -251,7 +251,7 @@ module ActionDispatch
|
|
251
251
|
args = []
|
252
252
|
|
253
253
|
model = record.to_model
|
254
|
-
name = if
|
254
|
+
name = if model.persisted?
|
255
255
|
args << model
|
256
256
|
model.model_name.singular_route_key
|
257
257
|
else
|
@@ -294,11 +294,12 @@ module ActionDispatch
|
|
294
294
|
when Class
|
295
295
|
@key_strategy.call record.model_name
|
296
296
|
else
|
297
|
-
|
298
|
-
|
299
|
-
|
297
|
+
model = record.to_model
|
298
|
+
if model.persisted?
|
299
|
+
args << model
|
300
|
+
model.model_name.singular_route_key
|
300
301
|
else
|
301
|
-
@key_strategy.call
|
302
|
+
@key_strategy.call model.model_name
|
302
303
|
end
|
303
304
|
end
|
304
305
|
|
@@ -13,14 +13,15 @@ require 'action_dispatch/routing/endpoint'
|
|
13
13
|
|
14
14
|
module ActionDispatch
|
15
15
|
module Routing
|
16
|
-
|
16
|
+
# :stopdoc:
|
17
|
+
class RouteSet
|
17
18
|
# Since the router holds references to many parts of the system
|
18
19
|
# like engines, controllers and the application itself, inspecting
|
19
20
|
# the route set can actually be really slow, therefore we default
|
20
21
|
# alias inspect to to_s.
|
21
22
|
alias inspect to_s
|
22
23
|
|
23
|
-
class Dispatcher < Routing::Endpoint
|
24
|
+
class Dispatcher < Routing::Endpoint
|
24
25
|
def initialize(defaults)
|
25
26
|
@defaults = defaults
|
26
27
|
@controller_class_names = ThreadSafe::Cache.new
|
@@ -85,7 +86,7 @@ module ActionDispatch
|
|
85
86
|
# A NamedRouteCollection instance is a collection of named routes, and also
|
86
87
|
# maintains an anonymous module that can be used to install helpers for the
|
87
88
|
# named routes.
|
88
|
-
class NamedRouteCollection
|
89
|
+
class NamedRouteCollection
|
89
90
|
include Enumerable
|
90
91
|
attr_reader :routes, :url_helpers_module
|
91
92
|
|
@@ -189,7 +190,7 @@ module ActionDispatch
|
|
189
190
|
end
|
190
191
|
end
|
191
192
|
|
192
|
-
class UrlHelper
|
193
|
+
class UrlHelper
|
193
194
|
def self.create(route, options, route_name, url_strategy)
|
194
195
|
if optimize_helper?(route)
|
195
196
|
OptimizedUrlHelper.new(route, options, route_name, url_strategy)
|
@@ -204,7 +205,7 @@ module ActionDispatch
|
|
204
205
|
|
205
206
|
attr_reader :url_strategy, :route_name
|
206
207
|
|
207
|
-
class OptimizedUrlHelper < UrlHelper
|
208
|
+
class OptimizedUrlHelper < UrlHelper
|
208
209
|
attr_reader :arg_size
|
209
210
|
|
210
211
|
def initialize(route, options, route_name, url_strategy)
|
@@ -280,14 +281,24 @@ module ActionDispatch
|
|
280
281
|
end
|
281
282
|
|
282
283
|
def handle_positional_args(controller_options, inner_options, args, result, path_params)
|
283
|
-
|
284
284
|
if args.size > 0
|
285
|
-
|
285
|
+
# take format into account
|
286
|
+
if path_params.include?(:format)
|
287
|
+
path_params_size = path_params.size - 1
|
288
|
+
else
|
289
|
+
path_params_size = path_params.size
|
290
|
+
end
|
291
|
+
|
292
|
+
if args.size < path_params_size
|
286
293
|
path_params -= controller_options.keys
|
287
294
|
path_params -= result.keys
|
288
295
|
end
|
289
296
|
path_params.each { |param|
|
290
|
-
|
297
|
+
value = inner_options.fetch(param) { args.shift }
|
298
|
+
|
299
|
+
unless param == :format && value.nil?
|
300
|
+
result[param] = value
|
301
|
+
end
|
291
302
|
}
|
292
303
|
end
|
293
304
|
|
@@ -337,7 +348,6 @@ module ActionDispatch
|
|
337
348
|
end
|
338
349
|
end
|
339
350
|
|
340
|
-
# :stopdoc:
|
341
351
|
# strategy for building urls to send to the client
|
342
352
|
PATH = ->(options) { ActionDispatch::Http::URL.path_for(options) }
|
343
353
|
FULL = ->(options) { ActionDispatch::Http::URL.full_url_for(options) }
|
@@ -368,7 +378,6 @@ module ActionDispatch
|
|
368
378
|
PATH.call(options)
|
369
379
|
end
|
370
380
|
}
|
371
|
-
# :startdoc:
|
372
381
|
|
373
382
|
attr_accessor :formatter, :set, :named_routes, :default_scope, :router
|
374
383
|
attr_accessor :disable_clear_and_finalize, :resources_path_names
|
@@ -443,7 +452,7 @@ module ActionDispatch
|
|
443
452
|
Routing::RouteSet::Dispatcher.new(defaults)
|
444
453
|
end
|
445
454
|
|
446
|
-
module MountedHelpers
|
455
|
+
module MountedHelpers
|
447
456
|
extend ActiveSupport::Concern
|
448
457
|
include UrlFor
|
449
458
|
end
|
@@ -474,6 +483,14 @@ module ActionDispatch
|
|
474
483
|
end
|
475
484
|
|
476
485
|
def url_helpers(supports_path = true)
|
486
|
+
if supports_path
|
487
|
+
@url_helpers_with_paths ||= generate_url_helpers(supports_path)
|
488
|
+
else
|
489
|
+
@url_helpers_without_paths ||= generate_url_helpers(supports_path)
|
490
|
+
end
|
491
|
+
end
|
492
|
+
|
493
|
+
def generate_url_helpers(supports_path)
|
477
494
|
routes = self
|
478
495
|
|
479
496
|
Module.new do
|
@@ -602,7 +619,7 @@ module ActionDispatch
|
|
602
619
|
end
|
603
620
|
private :build_conditions
|
604
621
|
|
605
|
-
class Generator
|
622
|
+
class Generator
|
606
623
|
PARAMETERIZE = lambda do |name, value|
|
607
624
|
if name == :controller
|
608
625
|
value
|
@@ -754,7 +771,7 @@ module ActionDispatch
|
|
754
771
|
options.delete(:script_name) || ''
|
755
772
|
end
|
756
773
|
|
757
|
-
def path_for(options, route_name = nil)
|
774
|
+
def path_for(options, route_name = nil)
|
758
775
|
url_for(options, route_name, PATH)
|
759
776
|
end
|
760
777
|
|
@@ -840,5 +857,6 @@ module ActionDispatch
|
|
840
857
|
raise ActionController::RoutingError, "No route matches #{path.inspect}"
|
841
858
|
end
|
842
859
|
end
|
860
|
+
# :startdoc:
|
843
861
|
end
|
844
862
|
end
|
@@ -38,18 +38,24 @@ module ActionDispatch
|
|
38
38
|
# # Test a custom route
|
39
39
|
# assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1')
|
40
40
|
def assert_recognizes(expected_options, path, extras={}, msg=nil)
|
41
|
-
|
41
|
+
if path.is_a?(Hash) && path[:method].to_s == "all"
|
42
|
+
[:get, :post, :put, :delete].each do |method|
|
43
|
+
assert_recognizes(expected_options, path.merge(method: method), extras, msg)
|
44
|
+
end
|
45
|
+
else
|
46
|
+
request = recognized_request_for(path, extras, msg)
|
42
47
|
|
43
|
-
|
48
|
+
expected_options = expected_options.clone
|
44
49
|
|
45
|
-
|
50
|
+
expected_options.stringify_keys!
|
46
51
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
52
|
+
msg = message(msg, "") {
|
53
|
+
sprintf("The recognized options <%s> did not match <%s>, difference:",
|
54
|
+
request.path_parameters, expected_options)
|
55
|
+
}
|
51
56
|
|
52
|
-
|
57
|
+
assert_equal(expected_options, request.path_parameters, msg)
|
58
|
+
end
|
53
59
|
end
|
54
60
|
|
55
61
|
# Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+.
|
@@ -25,5 +25,12 @@ module ActionDispatch
|
|
25
25
|
|
26
26
|
# Was there a server-side error?
|
27
27
|
alias_method :error?, :server_error?
|
28
|
+
|
29
|
+
def merge_default_headers(original, *args)
|
30
|
+
# Default headers are already applied, no need to merge them a second time.
|
31
|
+
# This makes sure that default headers, removed in controller actions, will
|
32
|
+
# not be reapplied to the test response.
|
33
|
+
original
|
34
|
+
end
|
28
35
|
end
|
29
36
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: actionpack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.2.
|
4
|
+
version: 4.2.1.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.2.
|
19
|
+
version: 4.2.1.rc1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.2.
|
26
|
+
version: 4.2.1.rc1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.6
|
33
|
+
version: '1.6'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.6
|
40
|
+
version: '1.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rack-test
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,28 +98,28 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - '='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 4.2.
|
101
|
+
version: 4.2.1.rc1
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - '='
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: 4.2.
|
108
|
+
version: 4.2.1.rc1
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: activemodel
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
113
|
- - '='
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: 4.2.
|
115
|
+
version: 4.2.1.rc1
|
116
116
|
type: :development
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
120
|
- - '='
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: 4.2.
|
122
|
+
version: 4.2.1.rc1
|
123
123
|
description: Web apps on Rails. Simple, battle-tested conventions for building and
|
124
124
|
testing MVC web applications. Works with any Rack-compatible server.
|
125
125
|
email: david@loudthinking.com
|
@@ -294,13 +294,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
294
294
|
version: 1.9.3
|
295
295
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
296
296
|
requirements:
|
297
|
-
- - "
|
297
|
+
- - ">"
|
298
298
|
- !ruby/object:Gem::Version
|
299
|
-
version:
|
299
|
+
version: 1.3.1
|
300
300
|
requirements:
|
301
301
|
- none
|
302
302
|
rubyforge_project:
|
303
|
-
rubygems_version: 2.
|
303
|
+
rubygems_version: 2.4.5
|
304
304
|
signing_key:
|
305
305
|
specification_version: 4
|
306
306
|
summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
|