David Moles
David Moles

Reputation: 51123

Suppress file extension detection / format mapping in Rails route

I have a Rails route of the form

get '/:collection/*files' => 'player#index'

where files is intended to be a semicolon-separated list of media files, e.g. /my-collection/some-video.mp4%3Bsome-audio.mp3

These are handled by a controller action of the form:

class PlayerController < ApplicationController
  def index
    @collection = params[:collection]
    @files = params[:files].split(';')
  end
end

and rendered with a template that displays an HTML5 <audio> or <video> element for each file.

This works fine so long as the files have no extension, e.g. /my-collection/file1%3Bfile2.

However, if I add the file extensions, /my-collection/foo.mp3%3Bbar.mp4, I get:

No route matches [GET] "/my-collection/foo.mp3%3Bbar.mp4"

And if I try it with a single file, e.g. /my-collection/foo.mp3, I get:

PlayerController#index is missing a template for this request format and variant. request.formats: ["audio/mpeg"] request.variant: []

Based on this answer I added a regex constraint to the route:

  get '/:collection/*files' => 'player#index', constraints: {files: /[^\/]+/}

This solves the No route matches problem, but now the multiple, separated version also fails with missing a template. (It's not ideal anyway, since I'd still rather allow / in file values. But /.*/ didn't work any better.)

I tried format: false, with and without constraints, and still got missing a template.

I also tried an ordinary path parameter (/:collection/:files), and got the same behavior as for the wildcard *files.

How can I get Rails to ignore and pass through the extension for this route?


Note: I'm using Rails 6.0.0 on Ruby 2.5.1.

Upvotes: 3

Views: 1159

Answers (1)

David Moles
David Moles

Reputation: 51123

Following the discussion on this Rails issue, the magic formula appears to be adding defaults: {format: 'html'} to format: false:

  get '/:collection/:files',
      to: 'player#index',
      format: false,
      defaults: {format: 'html'},
      constraints: {files: /.*/}

Upvotes: 6

Related Questions