I have a SchedulesController
which corresponds to a Schedule
class which is not an ActiveRecord model. The only action in SchedulesController
is show
.
Then I have a Shift
ActiveRecord model and a ShiftsController
.
In the schedules/show
view, there is a link the user can click to bring in a form for a new Shift
. This form is retrieved from the ShiftsController
via an ajax request. Because the request url will be packaged as schedules/shifts/new
, I need the shifts
routes to be nested within the schedules
routes.
However, I'd like to avoid generating all the RESTful routes for schedules
, just to keep things clean. I only need show
. This takes care of that:
# config/routes.rb
get "schedules/show"
resources :schedules, only: [] do
collection do
resources :shifts
end
end
Note that I use get "schedules/show"
because I don't want show
to be handled the usual way, where it requires an ID. I might change the show
action to display
to resolve that confusion. Anyway, here are the routes that this generates:
$ 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
This solution works; I can pull in the new_shift
form on the schedules/show
page. The problem is that it creates all the RESTful routes for schedules/shifts
, and I only need one right now, new
. So I tried this:
# config/routes.rb
get "schedule/show"
resources :schedules, only: [] do
collection do
resources :shifts, only: [:new]
end
end
And that's where I run into a problem. Here are the routes:
$ 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
That looks okay to me (?). But when I go to the schedules/show
page and click the link that's supposed to bring in the new_shift
form, I get this exception:
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'
I assume #<#<Class:0x7578de90>:0x7578d4d0>
refers to my Schedule
class, which as I said above is not an ActiveRecord model. But why does it not work here, but does when I do it the other way? In both cases, the GET /schedules/shifts/new(.:format)
route is exactly the same when I run rake routes
.
Any ideas? Thanks!
By Rails conventions, your form is trying to do a POST request to a path named shifts_path
, only it cannot find that path method because there isn't a route defined for the #create
action.
You need a route for #create
as well as #new
.
resources :shifts, only: [:new, :create]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.