禁止在 Rails 路由中检测文件扩展名/格式映射



我有一条形式的 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: /.*/}

最新更新