Seems that a bug was introduced in Rails 5. When we want to support dots in routes then the format is also set, even if the format is already part of a parameter.
I have the following route:
controller 'my_files' do
get 'my_files/:my_file' => :show, as: 'my_file', constraints: { my_file: %r{[^\/]+} }
end
And then I introduce urls like:
http://localhost:3000/my_files/ana.rb
http://localhost:3000/my_files/ana.json
The expected behavior and what actually happens in Rails 4.2.7.1 is that both urls work. Both include the file extension as part of the my_file attribute and the request format is html. This is the expected as behavior, as if the extension is part of the parameter it doesn't make sense that it is used for format too.
In Rails 5 and Rails 5.0.1 only the first url work. The second fails with
MyFilesController#show is missing a template for this request format and variant. request.formats: ["application/json"] request.variant: []
In this case the request format is json, although my_file is set to ana.json, which already includes the extension.
Rails version
As said it works with Rails 4.2.7.1 and it doesn't work with Rails 5 and Rails 5.0.1, so seems that the behaviour changed in Rails 5.
Ruby version
I tested it with ruby 2.4.1 and ruby 2.2.5
I think it is a bug and that should be fixed to keep the behavior of Rails 4. In case that is not, it is an important change and should be documented, and currently it is not. Also, another way to address the same behavior should be provided. Is there currently another way to do this? :confounded:
I set a simple project to test this in the two Rails version that I can share if needed.
@Ana06 this change was part of #20831 which was required for the new API application feature in Rails 5.0, previous to this the path parameter :format was nil and it was falling through to the default format of text/html. In this case it's better to be explicit, so turn off the :format path parameter and provide an explicit default of html so that it doesn't use the path, e.g:
scope format: false do
defaults format: 'html' do
constraints my_file: %r{[^\/]+} do
get 'my_files/:my_file', to: 'my_files#show', as: 'my_file'
end
end
end
You can write that in a single route if want by like this:
get 'my_files/:my_file',
to: 'my_files#show',
as: 'my_file',
format: false,
defaults: { format: 'html' },
constraints: { my_file: %r{[^\/]+} }
Sorry that it broke your application but the change is for the better.
Most helpful comment
@Ana06 this change was part of #20831 which was required for the new API application feature in Rails 5.0, previous to this the path parameter
:formatwasniland it was falling through to the default format oftext/html. In this case it's better to be explicit, so turn off the:formatpath parameter and provide an explicit default ofhtmlso that it doesn't use the path, e.g:You can write that in a single route if want by like this:
Sorry that it broke your application but the change is for the better.