Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
836 views
in Technique[技术] by (71.8m points)

ruby - Rails 4: Routing and sharing actions between controllers? What's the proper convention?

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>

  1. Why is this complete#action undefined from my TodoList#show view?
  2. What is the proper convention to share actions between controllers?

Thank you for your help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...