【问题标题】:"Create" route path helper“创建”路由路径助手
【发布时间】:2026-02-18 17:00:01
【问题描述】:

我发现资源路由方法很方便,但我完全讨厌它没有创建createdestroy 路径助手。

我理解写作

<% form_for(@object) %> 

应该自动获取路由名称,并且我们可以使用数组或符号来在它们存在时自动获取命名空间/前缀,但是我有许多具有复杂 scope 定义的路由,并且无法获取create_xxx 帮手让我很烦

没有比写更简单的解决方案吗? (我试图在生成帮助程序时保留默认的 RESTful URL)

complicated_scope do
  resources :my_resources, except: [:create, :destroy] do
    post '', on: :collection, action: :create, as: 'create' # plus this generates a pluralized version, not very intuitive `create_complicated_scope_my_resourceS_path`
    delete '', on: :member, action: :destroy, as: 'destroy'
  end
end

编辑。我的“有点复杂的范围”的例子

# Company access routes under /company/
namespace :company do
  # I need a company id for all nested controllers (this is NOT a resource strictly speaking, and using resources :companies, only: [] with 'on: :collection' doesn't generate appropriate urls)
  scope ':company_id' do
    # Company administrators
    namespace :admin do
      # There is a lot of stuff they can do, not just administration
      namespace :administration do
        # There are several parameters grouped in different controllers
        resources :some_administrations do
          ... # finally RESTful actions and others here
        end
      end
    end
  end
end

【问题讨论】:

  • 你能举出更多例子来说明你所使用的复杂范围吗?我认为复杂的范围可能是一种气味,如果您可以简化路由而不是通过寻找 create_xxx 助手来解决它,那么值得研究一下

标签: ruby-on-rails rest routes


【解决方案1】:

资源丰富的路由确实会创建 createdestroy 帮助器,但它们隐含在发出的 HTTP 请求的类型(分别为 POST 和 DELETE)中,因此路由帮助器方法应该可以与您提供的代码一起正常工作.

假设您有以下路由定义:

complicated_scope do
  resources :my_resources
  end
end

作为一个简单的例子,在删除的情况下,您可以使用这样的命名路由:

link_to "Delete [resource]", complicated_scope_resource_path(id: @my_resource.id), method: :delete

由于 HTTP 动词消除了控制器操作的歧义,此辅助方法路由到控制器的销毁方法。

或者,您也应该能够使用数组语法。

link_to "Delete [resource]",  [:complicated_scope, @my_resource], method: :delete

表单也是如此:

<%= form_for [:complicated_scope, @my_resource] do |f| %>

如果@my_resource 是一个新对象(未持久化),例如new 操作,这将等同于向/complicated_scope/my_resource 发送post 请求,其中表单参数进入正文的请求。

或者,如果@my_resource 存在,例如edit 操作,则上面的操作等效于发送PUT/PATCH,它将使用/complicated_scope/my_resource/:id/update 路由到控制器的update 操作。

【讨论】:

  • 啊,是的,我理解当对象存在时,路由的参数会自动更改为patch 方法。我经常为创建操作使用特殊形式(例如模态),并且我有一段完全不同的代码用于更新操作,所以我忘记了资源帮助器是用于“rails 方式”的_form 对象共享在创建和更新之间...
  • 是的,我认为这是典型的。更新对象的形式通常不同于创建的形式(至少在我的经验中)。但是,在这种情况下,上述内容仍然适用,您可以根据需要在表单中明确指定method: :postmethod: :patch