Commit bff61ba, while reducing allocations, caused a regression when an empty
format is passed to a route.
This can happen in cases where you're using an anchor tag, for example:
`https://example.com/parent/575256966.#child_1032289285`.
Because of this change `format` was getting sent in
`parameterized_parts` when previously it was not included. This resulted
in blank `format`'s being returned as `.` when if there was an extension
included it would be `.extension`. Since there was no extension this
caused incorrect URL's.
The test shows this would result in `/posts/show/1.` instead of
`/posts/show/1` which causes bad urls since the format is not present.
With changes made in 8363b8 and ae29142 cookies that are mutated on the
request like `cookies.signed = x` were not retained in subsequent tests,
breaking cookie authentiation in controller tests.
The test added demonstrates the issue.
The reason we need to select from non-deleted cookies is because without
checking the `@delete_cookies` the `cookie_jar` `@cookies` will send the
wrong cookies to be updated. The code must check for `@deleted_cookies`
before sending an `#update` with the requests cookie_jar cookies.
This follows how the cookie_jar cookies from the request were updated
before these changes.
In this commit, we set the content-type to `text/html` in AbstractController if the `options[:html]` is true so that we don't include ActionView::Rendering into ActionController::Metal to set it properly.
I removed the if `options[:plain]` statement because `AbstractController#rendered_format` returns `Mime::TEXT` by default.
* A string in the example lacked quotes.
* The tests asserted stuff about :last_name, whereas
test params do not have that key.
* But, the first one passed, why? After hitting my head against
the wall and doing some obscure rituals realized the new
#require had an important typo, wanted to iterate over the
array argument (key), but it ran over its own hash keys
(method #keys).
* Modified the test to prevent the same typo to happen again.
* The second test assigned to an unused variable safe_params
that has been therefore removed.
* Grammar of the second test description.
* Since I was on it, reworded both test descriptions.
This PR adds ability to accept arrays which allows you to require multiple values in one method. so instead of this:
```ruby
params.require(:person).require(:first_name)
params.require(:person).require(:last_name)
```
Here it will be one line for each params, so say if I require 10params, it will be 10lines of repeated code which is not dry. So I have added new method which does this in one line:
```ruby
params.require(:person).require([:first_name, :last_name])
```
Comments welcome
Since all controller instances are required to have a request and
response object, RackDelegation is no longer needed (we always have to
delegate to the response)
The following Rails code failed (with a `KeyError` exception) under
test:
```ruby
class ApplicationController < ActionController::Base
def user_strategy
# At this point:
# ```ruby
# session == {
# "user_strategy"=>"email",
# "user_identifying_value"=>"hello@world.com"
# }
# ```
if session.key?(:user_strategy)
session.fetch(:user_strategy)
end
end
end
```
When I checked the session's keys (`session.keys`), I got an array of
strings. If I accessed `session[:user_strategy]` I got the expected
`'email'` value. However if I used `session.fetch(:user_strategy)` I
got a `KeyError` exception.
This appears to be a Rails 4.2.4 regression (as the code works under
Rails 4.2.3).
Closes#21383
Controllers should always have a request and response when responding.
Since we make this The Rule(tm), then controllers don't need to be
somewhere in limbo between "asking a response object for a rack
response" or "I, myself contain a rack response". This duality leads to
conditionals spread through the codebase that we can delete:
* 85a78d9358/actionpack/lib/action_controller/metal.rb (L221-L223)
controller class resolution has been moved to the request object, so we
should override that method instead of relying on the RouteSet to
generate the controller class.
This refactoring moves the controller class name that was on the route
set to the request. The purpose of this refactoring is for changes we
need to move controller tests to integration tests, mainly being able to
access the controller on the request instead of having to go through
the router.
[Eileen M. Uchitelle & Aaron Patterson]
We should build the routes using the user facing API which is `Mapper`.
This frees up the library internals to change as we see fit. IOW we
shouldn't be testing internals.
the same value that is extracted from the options hash earlier is
returned, so we don't need to pass it in in the first place. The caller
already has the data, so stop passing it around.
We're going to try pulling this up further, and check `via` validity
sooner. This way we don't have to do a bunch of processing on `options`
hashes only to find out that the route is incorrect
we want to try to pull this logic up to where the user actually passed
in "controller" so that it's close to the related call. That way when
we're down the stack, we don't need to wonder "why are we doing this?"
The tests and methods were hard to read with `options[:options]` all
over the place. This refactoring makes the code easier to understand.
The change came out of work for moving the underlying code of controller
tests to integraiton tests.
Using the string version of the class reference is now deprecated when
referencing middleware. This should be written as a class not as a string.
Deprecation warning that this change fixes:
```
DEPRECATION WARNING: Passing strings or symbols to the middleware
builder is deprecated, please change
them to actual class references. For example:
"ActionDispatch::ShowExceptions" => ActionDispatch::ShowExceptions
```
We were doing extra work that could be pushed off to Integration test
and SharedRoutes. Creating an extra module isn't necessary when those
are created by their respective classes.
We should do the hard work outside the constructor. Also fix the tests
to not directly construct middleware objects, but to go through the
stack object.
ExceptionWrapper only cares about the backtrace cleaner, so lets just
pass the cleaner to the wrapper. It does not need to know that env
exists or what key the backtrace cleaner is stored in
This clears the transaction record state when the transaction finishes
with a `:committed` status.
Considering the following example where `name` is a required attribute.
Before we had `new_record?` returning `true` for a persisted record:
```ruby
author = Author.create! name: 'foo'
author.name = nil
author.save # => false
author.new_record? # => true
```
When executing an `ActionController::Parameters#fetch` with a block
that raises a `KeyError` the raised `KeyError` will be rescued and
converted to an `ActionController::ParameterMissing` exception,
covering up the original exception.
[Jonas Schubert Erlandsson & Roque Pinel]
This will silence deprecation warnings.
Most of the test can be changed from `render :text` to render `:plain`
or `render :body` right away. However, there are some tests that needed
to be fixed by hand as they actually assert the default Content-Type
returned from `render :body`.
We've started on discouraging the usage of `render :text` in #12374.
This is a follow-up commit to make sure that we print out the
deprecation warning.
This is another take at #14384 as we decided to wait until `master` is
targeting Rails 5.0. This commit is implementation-complete, as it
guarantees that all the public methods on the hash-inherited Parameters
are still working (based on test case). We can decide to follow-up later
if we want to remove some methods out from Parameters.
We shouldn't depend on specific methods imlemented in the TestResponse
subclass because the response could actually be a real response object.
In the future, we should either push the aliased predicate methods in
TestResponse up to the real response object, or remove them
The concurrent-ruby gem is a toolset containing many concurrency
utilities. Many of these utilities include runtime-specific
optimizations when possible. Rather than clutter the Rails codebase with
concurrency utilities separate from the core task, such tools can be
superseded by similar tools in the more specialized gem. This commit
replaces `ActiveSupport::Concurrency::Latch` with
`Concurrent::CountDownLatch`, which is functionally equivalent.
We should convert request parameters to a query string, then let the
request object parse that query string. This should give us results
that are more similar to the real-world
Instead of trying to manually clear out a request object, lets just
allocate a new one. The rack ENV is reused and cleaned (still), but the
request object is not.
Variants are typically set in the controller based on some attribute of
the request that the browser sent. We should make our tests more in
line with reality by doing the same and not mutating the request object.
Using `assert_predicate` and `assert_match` instead of just `assert` is
preferrable because better error messages are output.
In the case of `assert response.cookies.empty?` the error message was
`Failed assertion, no message given.` but now with `assert_predicate` it
will be `Expected {"user_name"=>"david"} to be empty?.`
For `assert_match(/user_name=david/,
response.headers["Set-Cookie"])` as well, the message returned was
unhelpful - `Failed assertion, no message given.` but now will tell what
was expected and what was returned with `Expected /user_name=david/ to
match "user_name=nope; path=/".`
Add the possibility to only filter parameters based on
their full path instead of relying on the immediate key.
config.filter_parameters += ['credit_card.code']
{ 'credit_card' => { 'code' => '[FILTERED]' },
'source' => { 'code' => '<%= puts 5 %>' } }
In 0de4a23 the behavior when there is a missing template was changed to
not raise an error, but instead head :no_content. This is a breaking
change and some gems rely on this happening.
To allow gems and other code to work around this, allow
`default_render` to take a block which, if provided, will
execute the contents of that block instead of doing the `head :no_content`.
This reverts commit 0b3397872582f2cf1bc6960960a6393f477c55e6, reversing
changes made to 56d52e3749180e6c1dcf7166adbad967470aa78b.
As pointed out on the PR, this will hide development mistakes too, which
is not ideal.
People should be free to mutate the header object, but not to set a new
header object. That header object may be specific to the webserver, and
we need to hide it's internals.
`ActionDispatch::SSL` changes headers to `Hash`.
So some headers will be broken if there are some middlewares
on ActionDispatch::SSL and if it uses `Rack::Utils::HeaderHash`.
Now ActionDispatch::Static can accept HTTP headers so that developers
will have control of returning arbitrary headers like
'Access-Control-Allow-Origin' when a response is delivered. They can
be configured through `#config.public_file_server.headers`:
config.public_file_server.headers = {
"Cache-Control" => "public, max-age=60",
"Access-Control-Allow-Origin" => "http://rubyonrails.org"
}
Also deprecate `config.static_cache_control` in favor of
`config.public_file_server.headers`.
ParamsWrapper was initially removed from API controllers according to
the following discusision:
https://github.com/rails-api/rails-api/issues/33
However, we're including it again so Rails API devs can decide
whether to enable or disable it.