The `cookies` method was not defined on ActionController::Base making the
permalink to the method not work.
Changing it to ActionController::Cookies make the reference a link.
The url_for helper now supports a new option called `bind_params`.
This is very useful in situations where you only want to add a required
param that is part of the route's URL but for other route not append an
extraneous query param.
Given the following router...
```ruby
Rails.application.routes.draw do
scope ":account_id" do
get 'dashboard' => 'pages#dashboard', as: :dashboard
get 'search/:term' => 'search#search', as: :search
end
delete 'signout' => 'sessions#destroy', as: :signout
end
```
And given the following `ApplicationController`
```ruby
class ApplicationController < ActionController::Base
def default_url_options
{ bind_params: { account_id: "foo" } }
end
end
```
The standard URLHelpers will now behave as follows:
```ruby
dashboard_path # => /foo/dashboard
dashboard_path(account_id: "bar") # => /bar/dashboard
signout_path # => /signout
signout_path(account_id: "bar") # => /signout?account_id=bar
search_path("quin") # => /foo/search/quin
```
UrlRewriter has been deleted in 2010 e68bfaf1fe
The url_rewriter_test is really testing url_for. Most of the tests are
identical.
This also move a couple tests that were not present in
`url_for_test.rb`.
Before this commit, some calls to render were hard-coding error
highlight as "not available". This was causing some error pages to show
the "you should install error highlight" message even though the right
version of error highlight was installed.
This commit adds a delegate method to the DebugView class so that the
debugging related templates can just ask whether or not error highlight
is available via a method call. That way we don't need to rely on
passing locals everywhere. The down side is that this change requires
all "rescue" templates to be rendered within the context of a DebugView
class (but I think that's OK)
When the Authorization header would contain a set of delimited values
where one or more values were blank, an ArgumentError would be raised.
This resolves that by removing blank values during parsing of the
Authorization header.
Also add some additional words to make it clear that the modules also
implement handling the exceptions configured with rescue_from, because
it was not immediately clear that happened without reading the code.
Most of these are redundant because rdoc handles these itself, but
`titlecase` on `ActiveSupport::Inflector` does not exist so that one is
just incorrect.
- Small wording tweaks for grammar or consistency
- Add links to methods/classes when possible, and fix some cases where
there were links but shouldn't be (`API`, `Testing`, etc.)
- Fixed `call-seq` for `each_key`
- Change `has_key?`, `key?`, and `member?` to aliases instead of
delegates so that they are documented as aliases (This is how the
methods are documented for Hash in Ruby)
- Remove explicit "also aliased as" docs because rdoc does this already
- Add `:nodoc:` to `EMPTY_ARRAY` and `EMPTY_HASH` constants since these
are internal optimizations
Background
----------
During integration tests, it is desirable for the application to respond
as closely as possible to the way it would in production. This improves
confidence that the application behavior acts as it should.
In Rails tests, one major mismatch between the test and production
environments is that exceptions raised during an HTTP request (e.g.
`ActiveRecord::RecordNotFound`) are re-raised within the test rather
than rescued and then converted to a 404 response.
Setting `config.action_dispatch.show_exceptions` to `true` will make the
test environment act like production, however, when an unexpected
internal server error occurs, the test will be left with a opaque 500
response rather than presenting a useful stack trace. This makes
debugging more difficult.
This leaves the developer with choosing between higher quality
integration tests or an improved debugging experience on a failure.
I propose that we can achieve both.
Solution
--------
Change the configuration option `config.action_dispatch.show_exceptions`
from a boolean to one of 3 values: `:all`, `:rescuable`, `:none`. The
values `:all` and `:none` behaves the same as the previous `true` and
`false` respectively. What was previously `true` (now `:all`) continues
to be the default for non-test environments.
The new `:rescuable` value is the new default for the test environment.
It will show exceptions in the response only for rescuable exceptions as
defined by `ActionDispatch::ExceptionWrapper.rescue_responses`. In the
event of an unexpected internal server error, the exception that caused
the error will still be raised within the test so as to provide a useful
stack trace and a good debugging experience.
This commit adds documentation to ShowExceptions explaining how it
should be configured in Rails applications. In addition, it adds more
`<code>` blocks to fix the formatting of some code snippets and prevent
the page from linking to itself.
This test was introduced in #19904.
In #21368 a bunch of test setup was removed, but the assignment
of `@set` was duplicated.
Removing the extraneous test setup means the test is identical to the
`test_cart_inspect` test.
This removes the test entirely.
This commit adds support for `:message_pack` and `:message_pack_allow_marshal`
as serializers for `config.action_dispatch.cookies_serializer`, just
like `config.active_support.message_serializer`.
The `:message_pack` serializer can fall back to deserializing with
`AS::JSON`, and the `:message_pack_allow_marshal` serializer can fall
back to deserializing with `AS::JSON` or `Marshal`. Additionally, the
`:marshal`, `:json`, and `:hybrid` / `:json_allow_marshal` serializers
can now fall back to deserializing with `AS::MessagePack`. These
behaviors make it easier to migrate between cookies serializers.
Fix: https://github.com/rails/rails/issues/48156
The assumption here is that in the overwhelming majority of
cases, all formats are valid.
So we first check if any of the formats is invalid before duping
the details hash and filtering them.
Additonally, by exposing a (non-public) `valid_symbols?` method, we
can check symbols are valid without resporting to `Array#%` which
would needlessly duplicate the `formats` array.
The `Type` class was introduced in https://github.com/rails/rails/pull/23085
for the sole purpose of breaking the dependency of Action View on Action Dispatch.
Unless you are somehow running Action View standalone, this is actually
never used.
So instead of delegating, we can use constant swapping, this saves us
a useless layer.
Ultimately we could consider moving `Mime::Types` into Active Support
but it requires some more thoughts.
Since 3.0, Rack doesn't guarantee rewindable request body streams.
Therefore Rack doesn't rewind the body after parsing the POST params
like it use to.
Since this is a test request, we can guarantee the stream is rewindable
and do it in the test.
Rails has incorrectly been adding leading dots to cookie domain values
when the `domain: :all` option is present.
This leading dot was required in cookies based on [RFC 2965][rfc2965]
(October 2000), but [RFC 6265][rfc6265] (April 2011) changed that
behaviour, making a leading dot strictly incorrect. Todays browsers aim
to confirm to RFC6265 with repect to cookies.
The new behaviour is that *any* cookie with an explicitly passed domain
is sent to all matching subdomains[[ref][mdn]]. For a server to indicate
that only the exact origin server should receive the cookie, it should
instead pass *no* domain attribute.
Despite the change in behaviour, browser devtools often display a cookie
domain with a leading dot to indicate that it is valid for subdomains -
this prefixed domain is *not* necessarily the raw value that was passed
in the Set-Cookie header. This explains why it's a common belief among
developers that the leading dot is required.
RFC6265 standard gives UAs an algorithm to handle old-style cookie
domain parameters (they can drop a leading dot if present), so it's
unlikely that this error would ever have had any effect on web browsers.
However, cookies generated this way can't be processed by Ruby's own
CGI::Cookie class:
> CGI::Cookie.new "domain" => ".foo.bar", "name" => "foo"
ArgumentError: invalid domain: ".foo.bar"
Newer versions of the Ruby CGI library accomodate the same fallback
behaviour (dropping the extra dot) but this isn't a justification for it
being the right way to set a cookie.
[mdn]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#domain_attribute
[rfc2965]: https://www.rfc-editor.org/rfc/rfc2965#section-3.2
[rfc6265]: https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1
In larger route files, or when routes are spread across multiple files,
it can be difficult to get from the output of the route inspector to the
relevant route definition.
This commit adds a route source location to the route, and uses that in
the HtmlTableFormatter (for rails/info and the debug exceptions
middleware) and the Expanded formatter (for `rails routes -E`).
To avoid doing extra work in production, it only sets the source location
in development.
This commit injects the application's backtrace cleaner so we can use it
to remove the rails root from the path. This also means we don't get
source locations for the routes defined by Rails.
If mounting an engine from a gem, we'll get a source location for where
we mount it in the application, but not for the routes defined in the
gem itself. That's probably good enough, since Rails already prints
routes for an engine separately under the title "Routes for
Foo::Engine".
Co-authored-by: John Hawthorn <jhawthorn@github.com>
Co-authored-by: Luan Vieira <luanzeba@github.com>
Co-authored-by: Daniel Colson <composerinteralia@github.com>
In 7c94708d24 the READMEs were included for
the main framework pages of the API documentation, except for Action Pack.
As Action Pack doesn't define any code in the ActionPack namespace, only
it's included modules (Action Dispatch, Action Controller and Abstract
Controller) are documented.
This adds documentation intro's to the main page for Action Controller
and Action Dispatch. The content was copied from the Action Pack README.
As Abstract Controller isn't mentioned there, it is skipped for now.
[ci-skip]
This is the same optimization applied in
a63ae913df
which I proposed in https://github.com/rails/rails/pull/47714
Here's the benchmark:
require "bundler/inline"
ROOT_STRING = '/'
TEST_PATH = "/some/path"
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
end
Benchmark.ips do |x|
x.report("path[0]") do
TEST_PATH[0] != ROOT_STRING
end
x.report("path.start_with?") do
TEST_PATH.start_with?(ROOT_STRING)
end
x.compare!
end
Warming up --------------------------------------
path[0] 942.044k i/100ms
path.start_with? 1.556M i/100ms
Calculating -------------------------------------
path[0] 9.463M (± 0.9%) i/s - 48.044M in 5.077358s
path.start_with? 15.611M (± 0.2%) i/s - 79.352M in 5.083056s
Comparison:
path.start_with?: 15611192.8 i/s
path[0]: 9463245.0 i/s - 1.65x slower
The sole purpose of `ActionController::Rendering#_normalize_args` is to
store the given block in `options[:update]`. This behavior was added
long ago in 6923b392b7 (as [part of
`ActionController::Base#_normalize_options`][part-of]) to support RJS.
Rails no longer supports RJS, so this override is no longer necessary.
[part-of]: 6923b392b7 (diff-febf2f89e7c197d6a9a7077c96031c68b2b7ac4d8ce7ec634de92b164e5f69adR100)
Expands the search field on the rails/info/routes page to also search:
* Route name (with or without a _path and _url extension)
* HTTP Verb (eg. GET/POST/PUT etc.)
* Controller#Action
because it's not obvious that the search field is currently only
restricted to the route paths.
Prevents horizontal scrolling on the rails/info/routes page when there
are long route names by introducing styled line breaks so that the table
will fit within the rendered width of the browser.
This is particularly relevant when there are a lot of nested namespaces
in a rails project and makes the page more readable, especially when
filtering with a search query.
The table headings have also been left-aligned so that they line up more
intuitively with the content and now that the table is no longer
horizontally scrolling, less space has been explicitly allocated for the
HTTP Verb column.
This is a refactor of the `Registry` module added in https://github.com/rails/rails/pull/47347. This is an attempt to
minimize the namespace conflcits that will happen when users will have a top level `Registry` module which can cause
incorrect behavior
Replace ActionView::ViewPaths::Registry with ActionView::PathRegistry
* Remove Copyright years
* Basecamp is now 37signals... again
Co-authored-by: David Heinemeier Hansson <dhh@hey.com>
---------
Co-authored-by: David Heinemeier Hansson <dhh@hey.com>
`ActionDispatch::Static` uses mixed-case headers and merges them with
lower case headers. This produces duplicate headers. Prefer lowercase
headers to avoid this situation.
Since rails/rails#47296, nothing sets the fullpath early, so changing
the path of a request, and then calling original_fullpath returns the
updated fullpath. This is a controller testing specific bug as
integration tests and real requests always have this header set, so I
think controller tests should too.
## Summary
This PR bumps RuboCop Performance to 1.16.0 and suppresses the following new offenses:
```console
% bundle exec rubocop
(snip)
Offenses:
actionpack/lib/action_dispatch/routing/mapper.rb:309:16:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if /#/.match?(to)
^^^^^^^^^^^^^^
actionpack/lib/action_dispatch/routing/mapper.rb:1643:18:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if /#/.match?(to)
^^^^^^^^^^^^^^
actionpack/lib/action_dispatch/routing/route_set.rb:887:67:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
path = Journey::Router::Utils.normalize_path(path) unless %r{://}.match?(path)
^^^^^^^^^^^^^^^^^^^^
actionpack/lib/action_dispatch/testing/assertions/routing.rb:86:12:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if %r{://}.match?(expected_path)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
actionpack/lib/action_dispatch/testing/assertions/routing.rb:205:14:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if %r{://}.match?(path)
^^^^^^^^^^^^^^^^^^^^
actionpack/lib/action_dispatch/testing/integration.rb:235:12:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if %r{://}.match?(path)
^^^^^^^^^^^^^^^^^^^^
actiontext/bin/webpack:18:6:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 150))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
actiontext/bin/webpack-dev-server:18:6:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 150))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb:120:64:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
elsif column.type == :uuid && value.is_a?(String) && /\(\)/.match?(value)
^^^^^^^^^^^^^^^^^^^^
railties/lib/rails/commands/secrets/secrets_command.rb:28:12:
C: [Correctable] Performance/StringInclude: Use String#include? instead of a regex match with literal-only pattern.
if /secrets\.yml\.enc/.match?(error.message)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3088 files inspected, 10 offenses detected, 10 offenses autocorrectable
```
## Additional Information
This behavior change is based on:
https://github.com/rubocop/rubocop-performance/pull/332
Previously, ActionDispatch::IllegalStateError was deprecated using
Module#deprecate_constant in 0b4b4c6b96.
This requires the -w flag to be used to actually see the deprecation
warning, and it can not be controlled using ActiveSupport::Deprecator
configuration.
This commit changes the deprecation to use #deprecate_constant from
ActiveSupport::Deprecation::DeprecatedConstantAccessor. This ensures
that the deprecation warning will be printed even without -w, and the
warning can be controlled by configuring ActionDispatch.deprecator
This error used to be a wrapper for a LoadError raised when
require_dependency was used to load helpers for controllers.
Since Zeitwerk does not use require_dependency, the only usage of the
error was removed in 5b28a0e972.
It was moved from action_controller/base/helpers.rb to its current
location in 28508d444e. At that time,
there were only two instances of is_missing being used: one in
action_controller/base/helpers and one in action_mailer/base/helpers.rb.
The action_mailer usage was moved to abstract_controller/helpers in
684c2dc208, and the action_controller
usage moved in 0e063f435c. This last
usage was later removed in 5b28a0e972,
leaving the require now unused.
Prior to this commit, the only out-of-the-box parsing that
`ActionDispatch::Testing::TestResponse#parsed_body` supported was for
`application/json` requests. This meant that `response.body ==
response.parsed_body` for HTML requests.
```ruby
get "/posts"
response.content_type # => "text/html; charset=utf-8"
response.parsed_body.class # => Nokogiri::HTML5::Document
response.parsed_body.to_html # => "<!DOCTYPE html>\n<html>\n..."
```
Using `parsed_body` for JSON requests supports `Hash#fetch`, `Hash#dig`,
and Ruby 3.2 destructuring assignment and pattern matching.
The introduction of [Nokogiri support for pattern
matching][nokogiri-pattern-matching] poses an opportunity to make assertions
about the structure of the HTML response.
On top of that, there is ongoing work to [introduce pattern matching
support in MiniTest][minitest-pattern-matching].
[nokogiri-pattern-matching]: https://github.com/sparklemotion/nokogiri/pull/2523
[minitest-pattern-matching]: https://github.com/minitest/minitest/pull/936
In the GitHub RoR monolith, we output the route URI pattern
in an HTML meta tag in our application layout for analysis
purposes. However, our current implementation is quite manual.
This change adds an attribute to requests with the URI pattern
of the matched route.
Co-authored-by: Rafael Mendonça França <rafael@rubyonrails.org>
Co-authored-by: Kate Higa <khiga8@github.com>
* Allow use of SSL-terminating reserve proxy that doesn't set headers
NGINX and other SSL-terminating reverse proxies can use HTTP headers to include forwarding information. If your stack includes SSL-termination through a network load balancer, that won't happen. You can use config.assume_ssl to address that.
* I hate these warts
* Document the new setting
* Add autoload for AssumeSSL
* Add CHANGELOG notice
Rack 3 introduces streaming bodies, which don't respond to `#each` and
MUST respond to `#call`. Ensure that the methods are correctly delegated.
`#to_ary` must also work correctly for enumerable bodies, and is used by
middleware like `Rack::ETag` to buffer enumerable bodies correctly.
Rack 3 response headers must be a mutable hash with lower-case keys. Rack
provides `Rack::Headers` as a compatibility layer for existing systems
which don't conform to this requirement. Prefer `Rack::Utils::HeaderHash`
on Rack 2, and `Rack::Headers` on Rack 3.
Remove some of the response test cases which test `nil` header keys as
these are considered invalid, and will fail with `Rack::Headers`.
In `6d5e0d2de2a8836e858962981c34aff2f76ffe3d` we added a `response=` method
that was redefining the already existed method generated by `attr_internal`.
Rack 2 includes this code, but in Rack 3 it was extracted into gems. These
gems include a v1 release compatible with Rack 2, and a v2 release
compatible with Rack v3+.
Rack 3 deprecates some of these clunky methods, and the only compatible
methods between Rack 2 and Rack 3 is to use `Rack::Response` which
includes `set_cookie` and `delete_cookie`.
When I was debugging `ActionDispatch::Request` instances in some tests, I
noticed IRB complaining that the object did not support `#inspect`, as
it was trying to print out the `method` which calls `check_method(nil)`
which fails. Don't try to validate `nil` method as it will always fail
and appears to be a valid state (when constructing an empty request as in
some tests).
The current implementation makes assumptions about the case and format of
headers. Introduce methods to handle headers in a case insensitive manner
and reduce churn when comparing with multi-value headers.
The current implementation makes assumptions about the order and case
sensitivity of cookie attributes. Introduce methods to parse those fields
and compare them semantically. Update the existing tests to take advantage
of these new assertions.
Ruby 3.2 significantly changed how instance variables are store.
It now use shapes, and in short, it's important for performance
to define instance variables in a consistent order to limit the
amount of shapes.
Otherwise, the number of shapes will increase past a point where
MRI won't be able to cache instance variable access. The impact
is even more important when YJIT is enabled.
This PR is data driven. I dump the list of Shapes from Shopify's
monolith production environment, and Rails is very present among
the top offenders:
```
Shape Edges Report
-----------------------------------
770 @default_graphql_name
697 @own_fields
661 @to_non_null_type
555 @own_interface_type_memberships
472 @description
389 @errors
348 @oseid
316 @_view_runtime
310 @_db_runtime
292 @visibility
286 @shop
271 @attribute_method_patterns_cache
264 @namespace_for_serializer
254 @locking_column
254 @primary_key
253 @validation_context
244 @quoted_primary_key
238 @access_controls
234 @_trigger_destroy_callback
226 @_trigger_update_callback
224 @finder_needs_type_condition
215 @_committed_already_called
214 @api_type
203 @mutations_before_last_save
202 @access_controls_overrides
201 @options
198 @mutations_from_database
190 @_already_called
183 @name
179 @_request
176 @own_arguments
175 @_assigns
175 @virtual_path
174 @context
173 @_controller
173 @output_buffer
173 @view_flow
172 @_default_form_builder
169 @cache
159 @_touch_record
151 @attribute_names
151 @default_attributes
150 @columns_hash
149 @attribute_types
148 @columns
147 @marked_for_same_origin_verification
146 @schema_loaded
143 @_config
143 @type
141 @column_names
```
All the changes are of similar nature, the goal is to preset the instance
variable to nil when objects are allocated, or when classes are created.
For classes I leverage the `inherited` hook. If the patern becomes common enough
it might make sense to add a helper for this in `ActiveSupport::Concern`.
We want to use error highlight with eval'd code, specifically ERB
templates.
Previously we could only get the information we needed by setting
`keep_script_lines` to true. In Ruby 3.2 and error_highlight we added
the ability to get this information without setting `keep_script_lines`.
This change implements that new behavior for Rails.
I removed the script line changes to support this in 3.1 because it is
not in any released version.
Ruby change: https://github.com/ruby/ruby/pull/6593
Erorr highlight change: https://github.com/ruby/error_highlight/pull/26
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
In #33418, documentation from `ActionView::Helpers::RenderingHelper#render`
was copied to `ActionController::Renderer#render` with the intention of
documenting `ActionController::Rendering#render`. Since then, further
documentation has been added to `ActionController::Renderer#render`, and
`ActionController::Renderer#render` has been mistaken for
`ActionController::Rendering#render` (for example, in #46045).
This commit adds documentation to `ActionController::Rendering#render`
(which was previously `:nodoc:` because it is a simple override of
`AbstractController::Rendering#render`), and updates related
documentation to point to `ActionController::Rendering#render`.
The w3.org RFC 2616 page displays an obtrusive "This document has been
superseded" overlay. In regard to the `Cache-Control` header, RFC 2616
has been superseded by RFC 7234, which, in turn, has been superseded by
RFC 9111.
Therefore, this commit replaces links to RFC 2616 with links to either
MDN or RFC 9111.
This clarifies the `ActiveSupport::ParameterFilter` documentation, and
tweaks the example code to be more friendly to the syntax highlighter
(similar to the tweaks made for `ActionDispatch::Http::FilterParameters`
in 782bed5d45).
This also trims the `ActionDispatch::Http::FilterParameters`
documentation, and links it to `ActiveSupport::ParameterFilter`, since
`ActiveSupport::ParameterFilter` is responsible for filter behavior.
Prior to this commit, the list of RFCs and URLs was jumbled in a single
paragraph (with no delimiters) that was associated with the `RFC2616`
constant.
This commit splits up the list, associating each RFC with its respective
constant, and incorporating each URL into a link.
This matches the indentation used in generated code, such as code from
`railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb.tt`.
This replaces two instances of /html/.match?(<string>) with the more
performant <string>.include?("html").
Performance/StringInclude was enabled in 3158bbb, however RuboCop does
not flag these two because it is unable to determine that the variable
passed to #match? is a string. In both these cases we know that the
variable must be a string (Mime::Type must be initialized with a string,
and Content-Type must be a string if present per Rack SPEC)
These were found by `rg '/\[\w ]+/\.match\?'`, and while this search
returns other entries they are either comments or in test files.
In #43487 we missed adding a changelog so that's been added here. In
addition, since this isn't a new framework default unless you are
creating a new application (and only in dev and test environments by
default) it can be easy to miss this new option. I've updated the
message to mention the option following DHH's suggestion on the original
PR.
Previously, ActionDispatch::IntegrationTest would always set
CONTENT_TYPE on the request whether or not the value being set was a
string or nil. However, Rack SPEC requires that if CONTENT_TYPE is set,
it must be a string.
Since the request_encoder can return nil for #content_type (and the
IdentityEncoder always will), IntegrationTest must check before it sets
the CONTENT_TYPE value.
A Rack::Lint test has been added to prevent regressions. Additionally,
it will make changes needed for Rack 3 more obvious when the time comes.
This patch reduces Array object allocations from some Rack middleware per each
request by reusing the Array object that wraps status, headers, and body
objects. This is a Rails version of the same improvements that has already been
pushed to Rack 3.0. https://github.com/rack/rack/pull/1887
When a host is not specified for an `ActionController::Renderer`'s env,
the host and related options will now be derived from the routes'
`default_url_options` and `ActionDispatch::Http::URL.secure_protocol`.
For example, with:
```ruby
Rails.application.default_url_options = { host: "rubyonrails.org" }
Rails.application.config.force_ssl = true
```
Before:
```ruby
ApplicationController.renderer.render inline: "<%= blog_url %>"
# => "http://example.org/blog"
```
After:
```ruby
ApplicationController.renderer.render inline: "<%= blog_url %>"
# => "https://rubyonrails.org/blog"
```
As a consequence, Action Text attachment URLs rendered in a background
job (a la Turbo Streams) will now use `Rails.application.default_url_options`.
Fixes#41795.
Fixeshotwired/turbo-rails#54.
Fixeshotwired/turbo-rails#155.
Currently if you do this:
```ruby
config.active_record.query_log_tags = [:namespaced_controller]
```
A request that's processed by the `NameSpaced::UsersController` will log as `namespaced_controller='NameSpaced%3A%3AUsersController'`.
By contrast if you set the tag to `:controller` it would log as `controller='user'`, much nicer.
This PR makes the `:namespaced_controller` formatting more similar to `:controller` - it will now log as `namespaced_controller='name_spaced/users'`.
ref: https://github.com/rails/rails/pull/46279
That PR missed the case where if you set `config.active_record.query_log_tags = [:namespaced_controller]`, it would log the controller twice:
```
/*namespaced_controller:Foo::BarController,controller:bar*
```
So this PR just fixes that bug, and tweaks the changelog entry rather than adding another one for the same bug.
This preallocates a `DEFAULT_ENV` Rack env for `Renderer` instances to
use, and avoids `dup`ing the `DEFAULTS` Hash unless the user intends to
modify it. This reduces retained allocations per controller class.
**Benchmark**
```ruby
# frozen_string_literal: true
require "benchmark/memory"
$controllers = []
Benchmark.memory do |x|
Class.new(ActionController::Base) # warmup
x.report("1 controller") do
$controllers << Class.new(ActionController::Base)
end
x.report("100 controllers") do
100.times { $controllers << Class.new(ActionController::Base) }
end
end
```
**Before**
```
Calculating -------------------------------------
1 controller 16.070k memsize ( 9.683k retained)
133.000 objects ( 40.000 retained)
50.000 strings ( 14.000 retained)
100 controllers 1.607M memsize ( 875.044k retained)
13.300k objects ( 3.308k retained)
50.000 strings ( 50.000 retained)
```
**After**
```
Calculating -------------------------------------
1 controller 15.654k memsize ( 9.347k retained)
129.000 objects ( 38.000 retained)
49.000 strings ( 14.000 retained)
100 controllers 1.565M memsize ( 841.284k retained)
12.900k objects ( 3.108k retained)
50.000 strings ( 50.000 retained)
```
This does add a `dup` to `render` because `request.routes = ...` mutates
the underlying env, which can now be `DEFAULT_ENV`. But a temporary
allocation there (likely outside of a request cycle) seems like a
reasonable trade for avoiding two retained allocations per controller
class.
Since engine initializers run later in the process, we need to run this
initializer earlier than the default.
This ensures they're all registered before the environments are loaded.
This fixes a few inaccuracies that have been present since
2db7304c2c. For example,
`Controller.renderer` no longer returns a class, `Renderer#env` is not
defined, and changing the value of `Renderer#defaults` has no direct
effect. This also documents the user-friendly Rack env key variants.
My app was raising a `CookieOverflow` exception but it was difficult to pinpoint the cause, since error trackers and logging system generally filter out cookies.
This Pull Request has been created because I want the exception to provide additional information:
- The name of the cookie that overflowed
- The magnitude of how much it overflowed by
I am assuming that only the cookie value is sensitive, and not its name or size.
In the case where a controller subclasses an engine's controller that,
in turn, subclasses a controller that includes the application's
`url_helpers` (for example, in the "isolated engine routes and helpers
are isolated to that engine" test in `railties/test/railties/engine_test.rb`),
this commit avoids allocating a new module per controller:
```ruby
ActionController::Base.include Rails.application.routes.url_helpers
C1 = Class.new(ActiveStorage::DirectUploadsController)
C2 = Class.new(ActiveStorage::DirectUploadsController)
C1.ancestors - C2.ancestors
# BEFORE:
# => [C1, #<Module:0x...>]
# AFTER:
# => [C1]
```
This commit also modifies the `RouteHelperIntegrationTest` test to use
the controllers defined in `actionpack/test/abstract_unit.rb`.
Otherwise, `extend AbstractController::Railties::RoutesHelpers.with(...)`
happens twice -- once for `ActionController::Base` and once for
`FakeACBase` -- which causes `FooController` to include an extra module
as it flip-flops its `_routes` definition. Previously, the extra module
only defined a `_routes` method; now, the extra module would be the
memoized dup of `routes.url_helpers`, which would cause the "only
includes one module with route helpers" test to falsely fail.
Using a `request` object that only "responds to the `host`,
`optional_port`, `protocol`, and `symbolized_path_parameter` methods"
has not been possible for a long time. For example,
`symbolized_path_parameter` was renamed to `path_parameters` (without
deprecation) in 925bd97566. And
`request.routes` and `request.original_script_name` methods became
required in 87a7591064. And a
`request.engine_script_name` method became required in
4080dd2f24.
Therefore, this commit updates the documentation to simply require
an `ActionDispatch::Request` instance.
Prior to this commit, the format of the code example confused the syntax
highlighter. This commit formats each explanation as a code comment,
and tweaks their wording for clarity.
- rename testcases
- reduce redundant parameters
- rename tested action methods
- move skip_parameter_encoding near by definiton of action
- add test for param_encoding
- Correct controller path "app/controller/books_controller.rb" to "app/controllers/books_controller.rb"
- Add space after "NOTE:"
Ref - https://github.com/rails/rails/pull/46342
Adding documentation to the API doc for `ActionDispatch::Routing::Mapper::Resources#draw` method,
inspired by the Rails Guide routing section. Also removed extra colon in title.
This commit adds `ActionView.deprecator` and replaces all usages of
`ActiveSupport::Deprecation.warn` in `actionview/lib` with
`ActionView.deprecator`. This commit also replaces a call to Ruby's
`Module#deprecate_constant` with Rails' `DeprecatedConstantProxy`, so
that its deprecation behavior can be configured using
`ActionView.deprecator`.
Additionally, this commit adds `ActionView.deprecator` to
`Rails.application.deprecators` so that it can be configured via
settings such as `config.active_support.report_deprecations`.
This commit also removes a few defunct `assert_deprecated` calls that
were not failing because they were nested in `assert_raises`, and the
raised error prevented checking the deprecation. (One was mistakenly
kept in d52d773946 when converting
`test_render_file_with_errors` to `test_render_template_with_errors`;
the other two were added in dd9991bac5 but
not removed when the deprecation was completed in
85ecf6e4098601222b604f7c1cbdcb4e49a6d1f0.)