参数路由与路由冲突解决与筛选路由

有时候我需要写一个页面能向show edit 那样可以接受参数的路由,弄了好久不知道怎样解决,今天恍然大悟

我们执行 rake routes 就会看到如下

                     wechat_nodes GET      /wechat/nodes(.:format)                                  wechat/nodes#index
                                  POST     /wechat/nodes(.:format)                                  wechat/nodes#create
                  new_wechat_node GET      /wechat/nodes/new(.:format)                              wechat/nodes#new
                 edit_wechat_node GET      /wechat/nodes/:id/edit(.:format)                         wechat/nodes#edit
                      wechat_node GET      /wechat/nodes/:id(.:format)                              wechat/nodes#show
                                  PATCH    /wechat/nodes/:id(.:format)                              wechat/nodes#update
                                  PUT      /wechat/nodes/:id(.:format)                              wechat/nodes#update
                                  DELETE   /wechat/nodes/:id(.:format)                              wechat/nodes#destroy

这是使用resources 生成一些路由,我们可以模仿写出自己的路由

我们看最后一列的内容, 对于show 来说 他的格式为/wechat/nodes/:id 再看edit 他的格式是/wechat/nodes/:id/edit

加入我们要想写一个/wechat/node/edit/34/topic/23 类似的路由,我们可以直接这样写

resources nodes do 
  collection do 
    get 'edit/:id/topic/:node_id', to: 'nodes#topic' , as: 'topic_edit'
  end
end

这里为什么会有一个as呢,因为没有as和其后面的名称的话,这样是没有前面的路由信息的.

筛选路由-路由冲突的解决方案

Rails项目有一个Article模型,对应ArticlesController控制器,其路由设置如下:

resources :articles do
end

这样它的CRUD路径就都自动创建出来了 ;)

现在我想再添加一个对Article模型搜索的页面,那么首先要在控制器中添加对应的search方法:

def search   
  render text:"hello search!!!"
end

然后在Article默认路由集合后面添加一行新路由:

get "articles/search",to:"articles#search"1

现在我们访问一下articles/search页面,咦?怎么出错了:

这里写图片描述

仔细看出错信息,原来Article之前的show路由恰恰可以匹配新的search路由,只不过原来的:id变成了search这个字符串哦.这就是为什么报Couldn’t find Article with id=search的原因了!

下面给出解决,我们只需要先禁用默认的show路由:

resources :articles,except:[:show] do    
  resources :comments
end

然后再生成一条筛选路由即可,所谓筛选路由就是对该路由内容进行细粒度匹配的方法:

get "articles/:id",to:"articles#show",constraints:{id:/\d+/}

路由都是从上之下依次匹配的,如果上面一条被匹配则路由匹配结束!这里只匹配id为数字的articles/xxx路径,所以search就会默认被忽略从而被后面search正确的路由所匹配!