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'
и решить, что с ними делать, прежде чем они туда доберутся.