Rails 4嵌套路由,没有所有RESTful路由

时间:2013-09-30 00:23:05

标签: ruby-on-rails rest activerecord rails-routing

我有一个SchedulesController,它对应一个Schedule类,它不是ActiveRecord模型。 SchedulesController中唯一的操作是show

然后我有一个Shift ActiveRecord模型和一个ShiftsController

schedules/show视图中,用户可以点击一个链接,为新的Shift引入表单。通过ajax请求从ShiftsController检索此表单。由于请求网址将打包为schedules/shifts/new,因此我需要将shifts路由嵌套在schedules路由中。

但是,我想避免为schedules生成所有RESTful路由,只是为了保持干净。我只需要show。这样可以解决这个问题:

# config/routes.rb

get "schedules/show"
resources :schedules, only: [] do
  collection do
    resources :shifts
  end
end

请注意,我使用的是get "schedules/show",因为我不希望show以通常的方式处理,因为它需要ID。我可能会将show操作更改为display以解决这种混淆。无论如何,这是由此产生的路线:

$ rake routes
Prefix         Verb   URI Pattern                          Controller#Action
schedules_show GET    /schedules/show(.:format)            schedules#show
shifts         GET    /schedules/shifts(.:format)          shifts#index
               POST   /schedules/shifts(.:format)          shifts#create
new_shift      GET    /schedules/shifts/new(.:format)      shifts#new
edit_shift     GET    /schedules/shifts/:id/edit(.:format) shifts#edit
shift          GET    /schedules/shifts/:id(.:format)      shifts#show
               PATCH  /schedules/shifts/:id(.:format)      shifts#update
               PUT    /schedules/shifts/:id(.:format)      shifts#update
               DELETE /schedules/shifts/:id(.:format)      shifts#destroy

此解决方案有效;我可以在new_shift页面上提取schedules/show表单。问题是它为schedules/shifts创建了所有RESTful路由,我现在只需要一个new。所以我尝试了这个:

# config/routes.rb

get "schedule/show"
resources :schedules, only: [] do
  collection do
    resources :shifts, only: [:new]
  end
end

这就是我遇到问题的地方。以下是路线:

$ rake routes
Prefix         Verb URI Pattern                     Controller#Action
schedules_show GET  /schedules/show(.:format)       schedules#show
new_shift      GET  /schedules/shifts/new(.:format) shifts#new

这看起来对我好(?)。但是,当我转到schedules/show页面并单击应该引入new_shift表单的链接时,我会遇到以下异常:

Started GET "/schedules/shifts/new" for 127.0.0.1 at 2013-09-29 19:59:52 -0400
  ActiveRecord::SchemaMigration Load (0.9ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by ShiftsController#new as HTML
  Rendered shifts/new.html.erb within layouts/application (135.6ms)
Completed 500 Internal Server Error in 272ms

ActionView::Template::Error (undefined method `shifts_path' for #<#<Class:0x7578de90>:0x7578d4d0>):
    1: <%= form_for @shift do |f| %>
    2:   <%= f.text_field :start_time %>
    3:   <%= f.text_field :end_time %>
    4: <% end %>
  app/views/shifts/new.html.erb:1:in `_app_views_shifts_new_html_erb__535553616_985195992'
  app/controllers/shifts_controller.rb:8:in `new'

我假设#<#<Class:0x7578de90>:0x7578d4d0>引用了我的Schedule类,如上所述,它不是ActiveRecord模型。但是为什么它在这里不起作用,但是当我以其他方式这样做时呢?在这两种情况下,当我运行GET /schedules/shifts/new(.:format)时,rake routes路线都完全相同。

有什么想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

通过Rails约定,您的表单尝试对名为shifts_path的路径执行POST请求,但只有它找不到该路径方法,因为没有为#create操作定义的路由。

您需要#create以及#new的路线。

resources :shifts, only: [:new, :create]