Rails ограничивает маршрутный символ определенным форматом

У меня есть маршрутный символ в моем routes.rb файл:

get "*client" => "client#show"

В контроллере я ищу клиента в базе данных и отображаю его пользовательскую страницу:

def show
  @client = Client.find_by(slug: params[:client])

  if @client.nil?
    render file: "client/404", layout: "error", status: :not_found
    return
  end
end

Это прекрасно работает, но моя проблема в том, что любой ресурс, который не найден, также направляется через мой client#show обработчик.

Это приводит к бессмысленному поиску в базе данных для клиента, а затем я получаю ошибку 500, потому что Rails не знает, как отобразить мою страницу ошибки для не-HTML форматов.

У меня вопрос: как я могу предотвратить попадание форматов, отличных от HTML, в мой обработчик подстановочных знаков?

Я пробовал следующее безрезультатно:

Ограничение формата

Помещение области вокруг маршрута, чтобы ограничить его форматом HTML:

scope :format => true, :constraints => { :format => 'html' } do
  get "*client" => "client#show"
end

Это удерживает ресурсы от перенаправления на мой обработчик, но, к сожалению, перенаправляет страницы на обработчик, только если они явно заканчиваются на .html расширение. Провал.

Формат по умолчанию

Затем я решил попробовать формат по умолчанию. Вот так:

get "*client" => "client#show", :defaults => { :format => 'html' }

К сожалению, до сих пор нет проблем. Там нет изменений. Насколько я понимаю, это просто устанавливает формат по умолчанию, если Rails не может понять это по заголовку типа содержимого или расширению файла.

Я начинаю думать, что не может быть способа сделать это на уровне маршрута.

2 ответа

Решение

Поскольку я не мог понять, как ограничить использование активов в моем обработчике на route Уровень, я просто поставил проверку в начале моего обработчика, чтобы закоротить обработчик, если запрос не в формате HTML.

def show
  render nothing: true, status: :not_found and return if invalid_format?
  ...
end

private

def invalid_format?
  request.format != "html"
end

Вы могли бы сделать что-то вроде этого и поставить перед get "*client" => "client#show" маршрут:

scope :format => true, :constraints => { :format => 'example' } do
  get "*client" => "error#404"
end

Установите форматы, которые вы хотите поймать, которые позже будут соответствовать общим get '*client' и решить, что с ними делать, прежде чем они туда доберутся.

Другие вопросы по тегам