Reputation: 8086
I'm building a Todo list in rails trying to learn how it all works. I'm having an issue with calling the action
of a controller from the view of another controller.
I have a TodoList
has_many TodoItem
and TodoItem
belongs_to TodoList
.
TodoList#Model
has_many :todo_items
def has_completed_items?
todo_items.complete.size > 0
end
def has_incompleted_items?
todo_items.incomplete.size > 0
end
TodoItem#Model
belongs_to :todo_list
scope :complete, -> { where("completed_at is not null") }
scope :incomplete, -> { where(completed_at: nil) }
def completed?
!completed_at.blank?
end
Routes
resources :todo_lists do
resources :todo_items do
member do
patch :complete
end
end
end
Patch generates this route:
complete_todo_list_todo_item PATCH
/todo_lists/:todo_list_id/todo_items/:id/complete(.:format)
todo_items#complete
Now I can call this path from my TodoItem
views without a problem like this: <%= link_to "Mark", complete_todo_list_todo_item_path(todo_item), method: :patch %>
After adding complete/incomplete scope
to my TodoItem
I added the following to my TodoList show view:
TodoList#Show
<% @todo_list.has_incompleted_items? %>
<% @todo_list.todo_items.incomplete.each do |item| %>
<li><%= item.content %></li>
<% end %>
This is properly displaying the incomplete items, so I tried to put a link to mark the item complete from within this view like this:
<% @todo_list.has_incompleted_items? %>
<% @todo_list.todo_items.incomplete.each do |item| %>
<li><%= item.content %>
<%= link_to "Mark", complete_todo_list_todo_item_path(item), method: :patch %></li>
<% end %>
Now this is where I get the following error:
NoMethodError in TodoLists#show undefined method `complete_todo_list_todo_items_path' for #<#:0x000001071cf540>
complete#action
undefined from my TodoList#show view?Thank you for your help.
Upvotes: 0
Views: 221
Reputation: 8086
I was able to solve this problem by removing the member
block from the routes file:
resources :todo_lists do
resources :todo_items do
patch :complete
end
end
Now my action route was updated to: todo_list_todo_item_complete
So from my view I had to call the new route with it's nested resource:
link_to "Mark", todo_list_todo_item_complete_path(@todo_list, item), method: :patch
Lastly I had to update my controller to locate the proper todo_item#id in the complete block:
@todo_item = @todo_list.todo_items.find(params[:todo_item_id])
Upvotes: 0