【问题标题】:Rails 4: Routing and sharing actions between controllers? What's the proper convention?Rails 4:控制器之间的路由和共享操作?什么是正确的约定?
【发布时间】:2014-01-22 23:52:04
【问题描述】:

我正在 Rails 中构建一个待办事项列表,试图了解它是如何工作的。我在从另一个控制器的视图中调用控制器的 action 时遇到问题。

我有一个TodoList has_many TodoItemTodoItem 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

路线

resources :todo_lists do
  resources :todo_items do
    member do
      patch :complete
    end
  end
end

补丁生成这条路由:

complete_todo_list_todo_item PATCH  
/todo_lists/:todo_list_id/todo_items/:id/complete(.:format) 
todo_items#complete

现在我可以从我的TodoItem 视图中调用此路径,而不会出现这样的问题:<%= link_to "Mark", complete_todo_list_todo_item_path(todo_item), method: :patch %>

将完整/不完整的scope 添加到我的TodoItem 后,我将以下内容添加到我的TodoList 显示视图中:

TodoList#Show

<% @todo_list.has_incompleted_items? %>
  <% @todo_list.todo_items.incomplete.each do |item| %>
    <li><%= item.content %></li>
<% end %>

这是正确显示不完整的项目,所以我尝试在这个视图中放置一个链接来标记项目完成,如下所示:

<% @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 %>

现在这是我得到以下错误的地方:

TodoLists 中的 NoMethodError#显示未定义的方法 #

的`complete_todo_list_todo_items_path'
  1. 为什么我的 TodoList#show 视图中未定义此 complete#action
  2. 在控制器之间共享操作的正确约定是什么?

感谢您的帮助。

【问题讨论】:

  • 嵌套资源不需要两个参数吗? complete_todo_list_todo_item_path(@todo_list, item)
  • @AbePetrillo 是的,我试过了,它也会导致错误。

标签: ruby ruby-on-rails-4


【解决方案1】:

我能够通过从路由文件中删除 member 块来解决这个问题:

resources :todo_lists do
  resources :todo_items do
    patch :complete
  end
end

现在我的行​​动路线更新为:todo_list_todo_item_complete

所以在我看来,我不得不用它的嵌套资源调用新路由:

link_to "Mark", todo_list_todo_item_complete_path(@todo_list, item), method: :patch

最后我必须更新我的控制器以在完整块中找到正确的 todo_item#id:

@todo_item = @todo_list.todo_items.find(params[:todo_item_id])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多