Commit 4f2cd3e9 introduced a bug by reordering the call to
`@controller.recycle!` above the call to `build_request_uri`. The
impact of this was that the `@_url_options` cache ends up not being
reset between building a request URI (occurring within the test
controller) and the firing of the actual request.
We encountered this bug because we had the following setup:
class MinimumReproducibleController < ActionController::Base
before_filter { @param = 'param' }
def index
render text: url_for(params)
end
def default_url_options
{ custom_opt: @param }
end
end
def test_index
get :index # builds url, then fires actual request
end
The first step in `get :index` in the test suite would populate the
@_url_options cache. The subsequent call to `url_for` inside of the
controller action would then utilize the uncleared cache, thus never
calling the now-updated default_url_options.
This commit fixes this bug calling recycle! twice, and removes a call
to set response_body, which should no longer be needed since we're
recycling the request object explicitly.
This is an option for to HTML content with a content type of
`text/html`. This rendering option calls `ERB::Util.html_escape`
internally to escape unsafe HTML string, so you will have to mark your
string as html safe if you have any HTML tag in it.
Please see #12374 for more detail.
This is as an option to render content with a content type of
`text/plain`. This is the preferred option if you are planning to render
a plain text content.
Please see #12374 for more detail.
This is an option for sending a raw content back to browser. Note that
this rendering option will unset the default content type and does not
include "Content-Type" header back in the response.
You should only use this option if you are expecting the "Content-Type"
header to not be set. More information on "Content-Type" header can be
found on RFC 2616, section 7.2.1.
Please see #12374 for more detail.
if the controller action has not yet streamed any data, actions should
process as normal, and errors should trigger the appropriate behavior
(500, or in the case of ActionController::BadRequest, a 400 Bad Request)
If we set :shallow_path when shallow is called it can result in incorrect
paths if the resource is inside a namespace because namespace itself sets
the :shallow_path option to the namespace path.
We fix this by removing the :shallow_path option from shallow as that should
only be turning shallow routes on and not otherwise affecting the scope.
To do this we need to treat the :shallow option to resources differently to
other scope options and move it to before the nested block is called.
This change also has the positive side effect of making the behavior of the
:shallow option consistent with the shallow method.
Fixes#12498.
MessageEncryptor has :serializer option, where any serializer object can
be passed. This commit make it possible to set this serializer from configuration
level.
There are predefined serializers (:marshal_serializer, :json_serialzier)
and custom serializer can be passed as String, Symbol (camelized and
constantized in ActionDispatch::Session namepspace) or serializer object.
Default :json_serializer was also added to generators to provide secure
defalt.
deep_munge solves CVE-2013-0155 security vulnerability, but its
behaviour is definately confuisng. This commit adds logging to deep_munge.
It logs keys for which values were set to nil.
Also mentions in guides were added.
The request attributes filtered_parameters, filtered_env and filtered_path
are memoized for performance reasons. However this can cause unusual
behavior in tests where there are multiple calls to get, post, etc.
Fixes#13803.
The revert is needed because of a regression described in #13369, routes
with trailing slash are no longer recognized properly.
This reverts commit 50311f1391ddd8e0349d74eb57f04b7e0045a27d.
* master: (536 commits)
doc, API example on how to use `Model#exists?` with multiple IDs. [ci skip]
Restore DATABASE_URL even if it's nil in connection_handler test
[ci skip] - error_messages_for has been deprecated since 2.3.8 - lets reduce any confusion for users
Ensure Active Record connection consistency
Revert "ask the fixture set for the sql statements"
Check `respond_to` before delegation due to: d781caaf31
Adding Hash#compact and Hash#compact! methods
MySQL version 4.1 was EOL on December 31, 2009 We should at least recommend modern versions of MySQL to users.
clear cache on body close so that cache remains during rendering
add a more restricted codepath for templates fixes#13390
refactor generator tests to use block form of Tempfile
Fix typo [ci skip]
Move finish_template as the last public method in the generator
Minor typos fix [ci skip]
make `change_column_null` reversible. Closes#13576.
create/drop test and development databases only if RAILS_ENV is nil
Revert "Speedup String#to"
typo fix in test name. [ci skip].
`core_ext/string/access.rb` test what we are documenting.
Fix typo in image_tag documentation
...
Conflicts:
actionpack/CHANGELOG.md
In Rails 3.2 you only needed pass an argument for dynamic segment once so
unique the segment keys array to match the number of args. Since the number
of args is less than required parts the non-optimized code path is selected.
This means to benefit from optimized url generation the arg needs to be
specified as many times as it appears in the path.
Fixes#12808
When an optimized helper fails to generate, show the full route constraints
in the error message. Previously it would only show the contraints that were
required as part of the path.
Fixes#13592
Using a Regexp to replace dynamic segments in a path string is fraught
with difficulty and can lead to odd edge cases like #13349. Since we
already have a parsed representation of the path it makes sense to use
that to generate an array of segments that can be used to build an
optimized route's path quickly.
Tests on a simple route (e.g. /posts/:id) show a speedup of 35%:
https://gist.github.com/pixeltrix/8261932
Calculating -------------------------------------
Current Helper: 5274 i/100ms
New Helper: 8050 i/100ms
-------------------------------------------------
Current Helper: 79263.6 (±3.7%) i/s - 395550 in 4.997252s
New Helper: 153464.5 (±4.9%) i/s - 772800 in 5.047834s
Tests on a more complex route show even an greater performance boost:
https://gist.github.com/pixeltrix/8261957
Calculating -------------------------------------
Current Helper: 2367 i/100ms
New Helper: 5382 i/100ms
-------------------------------------------------
Current Helper: 29506.0 (±3.2%) i/s - 149121 in 5.059294s
New Helper: 78815.5 (±4.1%) i/s - 398268 in 5.062161s
It also has the added benefit of fixing the edge cases described above.
Fixes#13349
Example:
# application routes.rb
mount BlogEngine => '/blog'
# engine routes.rb
get '/welcome' => redirect('')
This now redirects to the path `/blog`, whereas before it would redirect
to the application root path. In the case of a path redirect or a custom
redirect if the path returned contains a host then the path is treated as
absolute. Similarly for option redirects, if the options hash returned
contains a `:host` or `:domain` key then the path is treated as absolute.
Fixes#7977
In #5337 we forced the path encoding to ASCII-8BIT to prevent static
file handling from blowing up before an application has had chance to
deal with possibly invalid urls. However this has a negative side
effect of making it an incompatible encoding if the application's
public path has UTF-8 characters in it.
To work around the problem we check to see if the path has a valid
encoding once it has been unescaped. If it is not valid then we can
return early since it will not match any file anyway.
Fixes#13518
Like `format.any`, you can do the same with variants.
It works for both inline:
respond_to do |format|
format.html.any { render text: "any" }
format.html.phone { render text: "phone" }
end
and block syntax:
respond_to do |format|
format.html do |variant|
variant.any(:tablet, :phablet){ render text: "any" }
variant.phone { render text: "phone" }
end
end
TLDR: always return an object that responds to the query methods from
request.format, and do not touch Mime::Type[] lookup to avoid bugs.
---
Long version:
The initial issue was about being able to do checks like
request.format.html? for request with an unknown format, where
request.format would be nil.
This is where the issue came from at first in #7837 and #8085
(merged in cba05887dc3b56a46a9fe2779b6b228880b49622), but the
implementation went down the path of adding this to the mime type
lookup logic.
This unfortunately introduced subtle bugs, for instance in the merged
commit a test related to send_file had to be changed to accomodate the
introduction of the NullType.
Later another bug was found in #13064, related to the content-type being
shown as #<Mime::NullType:...> for templates with localized extensions
but no format included. This one was fixed in #13133, merged in
43962d6ec50f918c9970bd3cd4b6ee5c7f7426ed.
Besides that, custom handlers were not receiving the proper template
formats anymore when passing through the rendering process, because of
the NullType addition. That was found while migrating an application
from 3.2 to 4.0 that uses the Markerb gem (a custom handler that
generates both text and html emails from a markdown template).
---
This changes the implementation moving away from returning this null
object from the mime lookup, and still fixes the initial issue where
request.format.zomg? would raise an exception for unknown formats due to
request.format being nil.
When a route is mounted inside a resources block, it's automatically
prefixed, so a following code:
resources :users do
mount Blog::Engine => '/blog'
end
will generate a user_blog path helper.
In order to access engine helpers, we also use "mounted_helpers", a list
of helpers associated with each mounted engine, so a path to blog's post
can be generated using user_blog.post_path(user, post).
The problem I'm fixing here is that mount used a raw :as option, without
taking nestings into account. As a result, blog was added to a route set
as a `user_blog`, but helper was generated for just `blog`.
This commit applies the proper logic for defining a helper for a mounted
engine nested in resources or resource block.
(closes#8533)
Before ec16ba75a5493b9da972eea08bae630eba35b62f,
ActionView::Helpers::TranslationHelper#translate has raised errors with
specifying options[:raise] to true.
This should work by this fix:
begin
t(:"translations.missing", raise: true)
rescue I18n::MissingTranslationData
p :hello!
end
By default, variants in the templates will be picked up if a variant is set
and there's a match. The format will be:
app/views/projects/show.html.erb
app/views/projects/show.html+tablet.erb
app/views/projects/show.html+phone.erb
If request.variant = :tablet is set, we'll automatically be rendering the
html+tablet template.
In the controller, we can also tailer to the variants with this syntax:
class ProjectsController < ActionController::Base
def show
respond_to do |format|
format.html do |html|
@stars = @project.stars
html.tablet { @notifications = @project.notifications }
html.phone { @chat_heads = @project.chat_heads }
end
format.js
format.atom
end
end
end
The variant itself is nil by default, but can be set in before filters, like
so:
class ApplicationController < ActionController::Base
before_action do
if request.user_agent =~ /iPad/
request.variant = :tablet
end
end
end
This is modeled loosely on custom mime types, but it's specifically not
intended to be used together. If you're going to make a custom mime type,
you don't need a variant. Variants are for variations on a single mime
types.
This PR fixes#13064 regression bug introduced by the #8085
Now in _process_format when the format is a Mime::NullType nothing is written in self.content_type.
In this way the method Response#assign_default_content_type_and_charset can
write the the default mime_type.
A path redirect may contain any and all parts of a url which have different
escaping rules for each part. This commit tries to escape each part correctly
by splitting the string into three chunks - path (which may also include a host),
query and fragment; then it applies the correct escape pattern to each part.
Whilst using `URI.parse` would be better, unfortunately the possible presence
of %{name} parameters in the path redirect string prevents us from using it so
we have to use a regular expression instead.
Fixes#13110.
Extract **notable changes**, **deprecations** and **removals** from
each CHANGELOG.
I tried to reference the commits and pull requests for new features
and deprecations.
In the process I also made some minor changes to the CHANGELOGS.
The 4_1_release_notes guide is declared WIP.
Mention it in the changelog and add a test checking for regressions.
Hash#fetch isn't adding the defaultly returned value.
However, in the session, saving it is the behavior we should expect.
See discussion in #12692
Example:
# application routes.rb
mount BlogEngine => '/blog'
# engine routes.rb
get '/admin' => redirect('admin/dashboard')
This now redirects to the path `/blog/admin/dashboard`, whereas before it
would've generated an invalid url because there would be no slash between
the host name and the path. It also allows redirects to work where the
application is deployed to a subdirectory of a website.
Fixes#7977
This fixes an issue where the respond_with worked directly with the given
options hash, so that if a user relied on it after calling respond_with,
the hash wouldn't be the same.
Fixes#12029
In some instances, `assert_redirected_to` assertion was returning an
incorrect and misleading failure message when the assertion failed.
This was due to a disconnect in how the assertion computes the redirect
string for the failure message and how `redirect_to` computes the
string that is actually used for redirection.
I made the `_compute_redirect_to_loaction` method used by `redirect_to`
public and call that from the method `assert_redirect_to` uses to
calculate the URL.
The reveals a new test failure due to the regex used by
`_compute_redirect_to_location` allow `_` in the URL scheme.
The parameters are rendered as hidden form fields within the generated
form. This is useful for when a record has multiple buttons associated
with it, each of which target the same controller method, but which
need to submit different attributes.
:only and :except options for controller filters are now added before
:if and :unless. This prevents running :if and :unless procs when not
on the specified. Closes#11786.
Fix an issue where Journey was failing to clear the named routes hash when the
routes were reloaded and since it doesn't overwrite existing routes then if a
route changed but wasn't renamed it kept the old definition. This was being
masked by the optimised url helpers so it only became apparent when passing an
options hash to the url helper.
When generating an unnamed url (i.e. using `url_for` with an options
hash) we should skip anything other than standard Rails routes otherwise
it will match the first mounted application or redirect and generate a
url with query parameters rather than raising an error if the options
hash doesn't match any defined routes.
Fixes#8018
When helper try to require missing file rails will throw exception about
missing helper.
# app/helpers/my_helper.rb
require 'missing'
module MyHelper
end
And when we try do load helper
class ApplicationController
helper :my
end
Rails will throw exception. This is wrong because there is a helper
file.
Missing helper file helpers/my_helper.rb
Now when helper try to require non-existed file rails will throw proper
exception.
No such file to load -- missing
In order to get raw_post to be not empty after
ParamsParser#parse_formatted_parameters,
added rewinding of body stream input on parsing json params.
Closes#11345
Merge `:action` from routing scope and assign endpoint if both `:controller`
and `:action` are present. The endpoint assignment only occurs if there is
no `:to` present in the options hash so should only affect routes using the
shorthand syntax (i.e. endpoint is inferred from the the path).
Fixes#9856
Previously when app was mounted as following:
class Foo
def call(env)
[200, {}, [env['PATH_INFO']]]
end
end
RackMountRailsBug::Application.routes.draw do
mount RackTest.new => "/foo"
end
trailing slash was removed from PATH_INFO. For example requesting
GET /foo/bar/
on routes defined above would result in a response containing "/foo/bar"
instead of "/foo/bar/".
This commit fixes the issue.
(closes#3215)
This reverts commit b4239622afc4f3f73808fd0c97512f3a534e07dd, reversing
changes made to f99ce3c188f5dde57e2ff63e6a22363c62f0a4cd.
Reason: This broke the build
https://travis-ci.org/rails/rails/jobs/6629894
This commit adds support for passing additional url options along
with a :status option and any of the flash-related options to
`redirect_to` (i.e. :flash, :alert & :notice).
Closes#7570.
ActionView::Digestor now passes arguments correctly to
LookupContext::find method. This makes cache digests
respect the format option correctly.
FixtureFinder in tests also changed to reflect this.
The `force_ssl` command now builds the redirect url from `request.fullpath`.
This ensures that the format is maintained and it doesn't redirect to a route
that has the same parameters but is defined earlier in `routes.rb`. Also any
optional segments are maintained.
Fixes#7528.
Fixes#9061.
Fixes#10305.
If a file field tag is passed the multiple option, it is turned into an
array field (appending "[]"), but if the file field is passed an
explicit name as an option, leave the name alone (do not append "[]").
Fixes#9830
Add a note about getting the "no layout" behavior by returning "false"
to make it easier for people that might need to change their code.
Related to #8458. [ci skip]
* This unused variable is already removed from the code here. d18e8b1a3839c5c214e96c7e37e0d86febe15f99
* So removing it from CHANGELOG to be consistent with code
When setting the layout either by referencing a method or supplying a
Proc there is no way to fall back to the default lookup behavior if
desired. This patch allows fallback to the layout lookup behavior when
returning nil from the proc or method.
If the host in `default_url_options` is accidentally set with a protocol such as
```
host: "http://example.com"
```
then the generated url will have the protocol twice `http://http://example.com` which is not what the user intended. Likely they wanted to define a host `host: "example.com"` and a `protocol: "http://"` but did not know the convention.
This may not the most common problem, but when it happens it can go undetected for a while. I accidentally added `http://` out of habit recently only to find all the links in my emails were broken after deploying a demo site to production. Rather than allow this accident go undetected, we can fix the problem in line by properly setting the protocol and host.
I was able to find this related question on stack overflow: http://stackoverflow.com/questions/5878329/rails-3-devise-how-do-i-make-the-email-confirmation-links-use-secure-https-n where the answer was highly upvoted.
This is based off of work in #7415 cc/ @pixeltrix
ATP Action Mailer and Action Pack
The env hash passed to `Http::Headers#new` must be in env format.
Also be aware that the passed hash is modified directly.
docs and test-cases for setting headers/env in functional tests.
Follow up to #9700.
If an explicit name has been given and it already ends with "[]"
Before:
select(:category, [], {}, multiple: true, name: "post[category][]")
# => <select name="post[category][][]" ...>
After:
select(:category, [], {}, multiple: true, name: "post[category][]")
# => <select name="post[category][]" ...>
Closes#9466.
Passing `format: true` used to override the constraints: { format: /json/ }
with `/.+/`. This patch only sets the format if there is no constraint present.
Closes#7554.
This patch determines the `controller#action` directly
in the `match` method when the shorthand syntax is used.
this prevents problems with namespaces and scopes.
This seemed to be introduced in master by
9dd64f2e0c1b3ce85b503b0f81c50c93f89ffbcd, so there's no need to add a
changelog entry for fixing it.
[ci skip]
This reverts commit bb842e8d2111e50b21a14b8bd6d89371a4b9cd68, reversing
changes made to 40c287c7983c20c498f6a8a2ea49e9a6455347f7.
This was causing issues in one of our apps we just upgraded.
ActionController::RoutingError: No route matches [GET]
"/images/favicon.ico"
favicon_link_tag now returns '/images/favicon.ico' and in 3.2 returned
'/favicon.ico'
Browsers by default look for favicon.ico in the root directory
Conflicts:
actionpack/CHANGELOG.md
actionpack/lib/action_view/helpers/asset_tag_helper.rb
Previous implementation of time_zone_options_for_select did not dup the
ActiveSupport::TimeZone.all array. When :priority_zones were provided
the method would reject! the zones from the memoized TimeZones array
thus affecting future requests to the server. Essentially whatever
zones were specified as :priority_zones would show up for the first
request but then disappear from the time zone options on future
requests.
Print a message in both `rake routes` and at GET "/rails/info/routes"
that lets you know you have no routes defined, as well as linking to the
Rails Guide on the topic.
Currently, the img_alt method in ActionView keeps underscores
in the alt attribute. Because underscores are pronounced in
Apple's VoiceOver Utility, this has serious implications for
accessibility. This patch makes underscored or hyphenated file
names (both common in projects) read more naturally in screen
readers by replacing them with spaces. See method documentation
for details.
Added documentation to image_alt method
The current implementation only works correctly if you supply the `:controller`
with directory notation (eg. `:controller => 'admin/posts'`).
The ruby constant notation (eg. `:controller => 'Admin::Posts`) leads to unexpected problems with `url_for`.
This patch prints a warning for every non supported `:controller` option. I also added documentation how
to work with namespaced controllers. The warning links to that documentation in the rails guide.
previously when a partial was placed inside a directory
(eg. '/dir/_partial'), `assert_template` did not replace
the '_' prefix when looking through rendered tempaltes,
which resulted in an error.
I modified it to replace both, the leading '_' and the last '_'
after a '/'.
When debugging routes ,it can sometimes be difficult to understand exactly how the paths are matched. This PR adds a JS based path matching widget to the `/rails/info/routes` output. You can enter in a path, and it will tell you which of the routes that path matches, while preserving order (top match wins).
The matching widget in action:
![](http://f.cl.ly/items/3A2F0v2m3m1Z1p3P3O3k/path-match.gif)
Prior to this PR the only way to check matching paths is via mental math, or typing in a path in the url bar and seeing where it goes. This feature will be an invaluable debugging tool by dramatically decreasing the time needed to check a path match.
ATP actionpack
This commit changes route defaults so that explicit defaults are no
longer required where the key is not part of the path. For example:
resources :posts, bucket_type: 'posts'
will be required whenever constructing the url from a hash such as a
functional test or using url_for directly. However using the explicit
form alters the behavior so it's not required:
resources :projects, defaults: { bucket_type: 'projects' }
This changes existing behavior slightly in that any routes which
only differ in their defaults will match the first route rather
than the closest match.
Closes#8814
This now allows the use of arrays like this:
get '/foo/:action', to: 'foo', constraints: { subdomain: %w[www admin] }
or constraints where the request method returns an Fixnum like this:
get '/foo', to: 'foo#index', constraints: { port: 8080 }
Note that this only applies to constraints on the request - path
constraints still need to be specified as Regexps as the various
constraints are compiled into a single Regexp.
A declarative API for specifying dependencies that affect template
cache digest computation. In your controller, specify any of said
dependencies:
view_cache_dependency { "phone" if using_phone? }
When the block is evaluated, the resulting value is included in the
cache digest calculation, allowing you to generate different digests
for effectively the same template. (Mostly useful if you're mucking
with template load paths.)
Previously rendering a partial without giving :object or :collection
would generate a local variable with the partial name by default.
This was noticed due to warnings in Ruby 2.0 of not used variables,
which turned out to be the generation of not used variables inside
partials that do not contain objects related to them.