2015-01-31 2 views
0

У меня есть подстановочный маршрут в моем routes.rb файле:Rails ограничить подстановочный маршрут к определенному формату

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 в моем подстановочном коде?

Я попытался следующие без толку:

Формат Constraint

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

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

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

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

Далее, я думал, что попробовать формат по умолчанию. Например:

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

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

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

ответ

0

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

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

private 

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

Ruby <2.2? Не конвертируйте неизвестные входы в символы, или ваше приложение будет подвергаться атакам из аутсорсинга DoS (в этом случае требуется несколько форматов); вместо этого используйте 'request.format! = 'html'' – mdesantis

+0

Полезно знать. Спасибо @mdesantis. Обновлен мой ответ. –

0

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

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

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

+0

Спасибо за ответ. Я бы предпочел, однако, не создавать маршрут для всех возможных форматов. –

Смежные вопросы