将相同的路由/不同的HTTP动词匹配到Rails中的不同控制器方法

时间:2014-06-11 12:55:04

标签: ruby-on-rails-3 url-routing

我有一个Rails 3应用程序,而不是默认的销毁映射:

modelname DELETE         /modelname/:id           modelname#destroy

我想要一个GET'后备'的专用路线,以便没有Javascript的用户被发送到确认页面:

delete_modelname DELETE  /modelname/:id/delete    modelname#destroy
delete_modelname GET     /modelname/:id/delete    modelname#confirm_destruction

我可以使用以下声明在rake routes中获得上述输出:

resources :modelname, except: [:destroy] do
  member {
    get 'delete', to: 'confirm_destruction'
    delete 'destroy', as: 'delete'
  }
end

然而,其中一条路线不匹配,并且它似乎是依赖于顺序的,即首先定义的那个然后在测试中不匹配。我注意到Rails生成的默认“重载”路由在rake routes中看起来有点不同:

modelnames GET          /modelname/:id/delete    modelname#index
           POST         /modelname/:id/delete    modelname#create

路由名称不会重复,指向create的链接将成为表单或启用Javascript的请求之外index的链接。

似乎我已经定义了两个完全独立的路由,它们共享相同的名称,而不是按照我的意图重载路径。

我错过了什么?有没有办法得到我正在寻找的效果?

我尝试过的事情

由于它似乎是冲突的路线名称,我尝试了这个:

member {
  get 'delete', to: 'confirm_destruction'
  delete 'destroy', path: 'delete'
}

as:更改为path:,以便路径名称不会受到影响,但路径会匹配。这有效!生成以下路由:

delete_modelname GET     /modelname/:id/delete    modelname#confirm_destruction
modelname DELETE         /modelname/:id/delete    modelname#destroy

这给出了我之后的效果,但不幸的是modelname DELETE路由掩盖了更新的默认modelname PUT路由。

1 个答案:

答案 0 :(得分:0)

好的,有一种方法可以做到这一点,但它并不像我希望的那么优雅。如果有人有一个更好的答案我会很开放。

resources :modelname, except: [:destroy] do
  member {
    get 'delete', to: 'confirm_destruction'
    delete 'destroy', as: 'destroy', path: 'delete'
  }
end

这很有效,因为这两条新路线在视图中使用了唯一的名称 - delete_modelname_pathdestroy_modelname_path - 但如果禁用了Javascript,则destroy_modelname路径仍为/modelnames/:id/delete ,作为GET请求进入,Rails将其匹配到delete_modelname路由(即确认页面)。