自定义Rails的默认资源路由路径

时间:2015-07-08 12:35:00

标签: ruby-on-rails ruby routing

TL; DR

我想更改Rails资源路由的默认行为,移动所有资源的create路径,使其成为/resources/new而不是/resources的POST。


设置

让我们假设一条如此指定的资源丰富的路线:

# routes.rb

resources :events


将生成的实际路线是:

$ rake routes

    Prefix Verb   URI Pattern                Controller#Action
    events GET    /events(.:format)          events#index
           POST   /events(.:format)          events#create
 new_event GET    /events/new(.:format)      events#new
edit_event GET    /events/:id/edit(.:format) events#edit
     event GET    /events/:id(.:format)      events#show
           PATCH  /events/:id(.:format)      events#update
           PUT    /events/:id(.:format)      events#update
           DELETE /events/:id(.:format)      events#destroy

N.B。 create操作由/events路径的POST触发。


现在,如果我想更改该路径,我可以“按手动”执行,基于每个资源:

# routes.rb

# I've placed the routes in this order, and used `as: "new_event"`,
# to avoid generating an `events_new` path helper.

post 'events/new' => 'events#create', as: "new_event"
resources :events, except: [:create]


以下是生成的路线:

$ rake routes

    Prefix Verb   URI Pattern                Controller#Action
 new_event POST   /events/new(.:format)      events#create
    events GET    /events(.:format)          events#index
           GET    /events/new(.:format)      events#new
edit_event GET    /events/:id/edit(.:format) events#edit
     event GET    /events/:id(.:format)      events#show
           PATCH  /events/:id(.:format)      events#update
           PUT    /events/:id(.:format)      events#update
           DELETE /events/:id(.:format)      events#destroy


大! create操作现在由/events/new路径的POST而不是/events路径触发。

其他所有路径/助手的行为与之前完全相同 - 包括对/events/new的GET以及new_event路径/网址助手。


问题

有没有办法只更改用于该特定操作的默认路径,而不是手动覆盖每个create操作?

如果做不到这一点,我还可以使用其他方法来改变一堆资源丰富的路线,以便他们的创建动作如上所述移动到/new

谢谢!

1 个答案:

答案 0 :(得分:1)

您可以通过在一个位置添加一个覆盖您的模块来简化您的生活。例如:

module MyResources
  def my_resources(resource_name, opts = {}, &block)
    opts = opts.merge(except: [:create])

    resources(resource_name, opts, &block)
    post "#{resource_name}/new" => "#{resource_name}#create", as: "new_{resource_name}"    
  end
end

ActionDispatch::Routing::Mapper.__send__ :include, MyResources

然后在你的routes.rb中你可以这样做:

my_resources :events