Rails route appears in routes but throws a 404

社会主义新天地 提交于 2019-12-24 02:16:26

问题


I'm trying to add a simple route to an existing controller/action but strangely I'm getting a 404 error even though the route appears to exist.

Here's the relevant section of my 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

It seems correct because here's what I see when I check:

$ 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

I also see an expected response in the console:

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

Yet, when I try to visit /wine/semi-sweet/ (Semi-sweet is a style "slug" which I use to search in the action) I get a 404 error.

What could I me missing? I've searched dozens of similar questions on S.O. and none of the solutions apply to my situation.


回答1:


It seems you need to specify constraints. When you say 'wines/semi-sweet', how would the router decide whether it's a style_detail path or a colletion_detail path? They both have the same mask '/wines/:something'

It should be something like:

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

This way the router will match predefined words (could be an array too) with wine styles, all the other strings will be considered as wine collections.

But it would be best to change the mask for these two paths, just to be safe, for example:

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


来源:https://stackoverflow.com/questions/41881523/rails-route-appears-in-routes-but-throws-a-404

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!