2017-01-26 3 views
1

Я пытаюсь добавить простой маршрут к существующему контроллеру/действию, но, как ни странно, я получаю ошибку 404, хотя маршрут, похоже, существует.Маршрут Rails появляется в маршрутах, но выбрасывает 404

Вот соответствующий раздел моего routes.rb:

# Wines 
    scope 'wine' do 
    get '/',     to: 'wines#index',    as: 'wine_index' 
    get '/:collection',  to: 'wines#collection_detail', as: 'collection_detail' 
    get '/:collection/:slug', to: 'wines#wine_detail',  as: 'wine_detail' 
    get '/:style',   to: 'wines#style_detail',  as: 'style_detail' 
    end 

кажется правильным, потому что вот что я вижу, когда я проверяю:

$ rake routes 
=> 

      Prefix Verb  URI Pattern            Controller#Action 

     wine_index GET  /wine(.:format)           wines#index 
collection_detail GET  /wine/:collection(.:format)        wines#collection_detail 
     wine_detail GET  /wine/:collection/:slug(.:format)      wines#wine_detail 
     style_detail GET  /wine/:style(.:format)         wines#style_detail 

        GET|POST /*path(.:format)           pages#error404 

Я также вижу ожидаемый отклик в консоли:

2.3.1 :003 > app.style_detail_path('semi-dry') 
=> "/wine/semi-dry" 

Тем не менее, когда я пытаюсь посетить /wine/semi-sweet/ (Se mi-sweet - это стиль «slug», который я использую для поиска в действии). Я получаю ошибку 404.

Что я могу потерять? Я искал десятки подобных вопросов по S.O. и ни одно из решений не относится к моей ситуации.

+0

Что произойдет, если вы удалите слэш? – jvillian

+0

@jvillian Без изменений. Еще 404 – emersonthis

+0

Pls публикует сообщение об ошибке с вашего терминала. – jvillian

ответ

2

Кажется, вам нужно указать ограничения. Когда вы говорите «вина/полусладкие», как маршрутизатор может решить, является ли это стилем стиля или пути colletion_detail? Они оба имеют ту же маску «/ вино /: что-то»

Это должно быть что-то вроде:

scope 'wine' do 
    get '/',     to: 'wines#index',    as: 'wine_index' 
    get '/:style',   to: 'wines#style_detail',  as: 'style_detail', constraints: proc { |r| Style.include?(r.params[:style]) } 
    get '/:collection',  to: 'wines#collection_detail', as: 'collection_detail' 
    get '/:collection/:slug', to: 'wines#wine_detail',  as: 'wine_detail' 
    end 

Таким образом, маршрутизатор будет соответствовать заранее определенным словам (может быть массивом тоже) с вином стилями, всеми другие струны будут рассматриваться как коллекции вин.

Но было бы лучше, чтобы изменить маску для этих двух путей, на всякий случай, например:

get '/:style',   to: 'wines#style_detail',  as: 'style_detail' 
    get '/c/:collection',  to: 'wines#collection_detail', as: 'collection_detail' 
+0

Yup. Я только начинал замечать это. Интересно, почему Rails не предупреждает меня об этом так, как это делается при попытке создать дублирующее имя пути. – emersonthis

+0

Маршрутизатор бросает 404, потому что сначала у вас есть путь к коллекции, поэтому он ищет коллекцию с именем «полусухая», которой не существует. Но просто переупорядочивание маршрутов не поможет, вам нужно указать ограничения или изменить «маску» –

+0

Право. Я понял. Мне просто интересно, почему «рейк-маршруты» выдадут полезную ошибку, если вы попытаетесь назвать два маршрута одинаковыми (Ex: 'wine_detail' и' wine_detail'), но он вообще не жаловался на мои конфликтующие маршруты (Ex : '/ wine /: something' и'/wine /: something-else', которые фактически являются точно такими же) – emersonthis

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