I am building a To Do application in an attempt to get fluent with Rails. There are four levels of hierarchy in my app.
- User
- Goals (multiple goals per user)
- Tasks (multiple tasks per goal)
- Subtasks (multiple subtasks per task)
I have a working front end form for each of these that utilizes nested resources. My routes.rb has something like this
resources :goal do
resources :task do
resources :subtask
end
end
What I would like to do now is that have all these forms right in one of the views of the user controller.
This the form that I have attempted to create :
<%= form_for @task, url: {controller: 'task', action: 'create'} do |f| %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.submit "Add Goal", class: "btn" %>
<% end %>
But I end up getting this error
No route matches {:action=>"create", :controller=>"task", :id=>"1"}
The :id=>1 corresponds to the user page I am on (http://localhost:3000/user/1)
What I understand is that there is that nowhere have I provided the goal_id for which this step is intended. No idea how to implement this.
Another thing that I have noticed is that a response to rake routes
shows a lot of URI paths but nothing for POST method. It does not allow me to use a path from there in the url:
in form_for
because it does not match the POST method.
So my questions are :
- How to route a form_for that when you have nested resources?
- How to provide the ID of the parent resource while using form_for so that my create action is correctly routed?
It is typically bad practice to nest routes beyond two levels deep. I would change your routes to:
and
Now if you run "bundle exec rake routes" in the command line you will see all of the nested routes and their corresponding helpers. Your current issue lies with the form_for method. You need to add the resource its nested with which in this case should be:
Lastly, @goal is also still undefined so you'll need to define it in your 'new' action in the tasks controller. This is normally done by passing the id of the goal your task will be associated with via the params hash and the "link_to" used to get to the 'new' form. Then in the new action in your tasks controller:
Then in your 'create' action you should have the association made: