我有一条形式的 Rails 路线
get '/:collection/*files' => 'player#index'
其中files
旨在以分号分隔的媒体文件列表,例如/my-collection/some-video.mp4%3Bsome-audio.mp3
这些由以下形式的控制器操作处理:
class PlayerController < ApplicationController
def index
@collection = params[:collection]
@files = params[:files].split(';')
end
end
并使用为每个文件显示 HTML5<audio>
或<video>
元素的模板呈现。
只要文件没有扩展名,这就可以正常工作,例如/my-collection/file1%3Bfile2
.
但是,如果我添加文件扩展名,/my-collection/foo.mp3%3Bbar.mp4
, 我得到:
没有路由匹配 [GET] "/my-collection/foo.mp3%3Bbar.mp4">
如果我尝试使用单个文件,例如/my-collection/foo.mp3
,我得到:
玩家控制器#索引缺少此请求格式和变体的模板。 request.formats: ["audio/mpeg"] request.variant: []
基于这个答案,我在路由中添加了一个正则表达式约束:
get '/:collection/*files' => 'player#index', constraints: {files: /[^/]+/}
这解决了无路由匹配问题,但现在多个单独的版本也因缺少模板而失败。(无论如何,这并不理想,因为我仍然宁愿允许在文件值中/
。但/.*/
并没有更好。
我尝试了format: false
,有和没有constraints
,但仍然缺少模板。
我还尝试了一个普通路径参数(/:collection/:files
(,并得到了与通配符*files
相同的行为。
如何让 Rails 忽略并通过此路线的扩展?
注意:我在Ruby 2.5.1上使用Rails 6.0.0。
在讨论这个 Rails 问题之后,神奇公式似乎在format: false
中添加了defaults: {format: 'html'}
:
get '/:collection/:files',
to: 'player#index',
format: false,
defaults: {format: 'html'},
constraints: {files: /.*/}