有时候我需要写一个页面能向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正确的路由所匹配!