SmartAnswers::Application.routes.draw do
  get 'healthcheck', to: proc { [200, {}, ['']] }

  constraints id: /[a-z0-9-]+/i do
    get '/:id/visualise(.:format)', to: 'smart_answers#visualise', as: :visualise

    get '/:id(/:started(/*responses)).:format',
      to: 'smart_answers#show',
      as: :formatted_smart_answer,
      constraints: { format: /[a-zA-Z]+/ }

    get '/:id(/:started(/*responses))', to: 'smart_answers#show', as: :smart_answer
  end
end

SmartAnswers::Application.routes.draw do
  get 'healthcheck', to: proc { [200, {}, ['']] }

  constraints id: /[a-z0-9-]+/i do
    get '/:id/visualise(.:format)', to: 'smart_answers#visualise', as: :visualise

    get '/:id(/:started(/*responses)).:format',
      to: 'smart_answers#show',
      as: :formatted_smart_answer,
      constraints: { format: /[a-zA-Z]+/ }

    get '/:id(/:started(/*responses))',
      to: 'smart_answers#show',
      as: :smart_answer,
      format: false
  end
end

Set smart_answer path route format to false.
Set smart_answer path route format to false.

This brings back the default rails 3.x behaviour. The new one matches
numbers in paths like /pension-amount/300.0 as format and throws an
exception.
