【问题标题】:How to map a resource to more than one helper in rails?如何将资源映射到rails中的多个助手?
【发布时间】:2013-10-08 18:49:17
【问题描述】:

我有一个 Profile 模型,它由 Customer 和 Vendor 模型继承。 个人资料 has_many :posts.

当我这样做时

form_for [ @profile, @post ] do |f|

form_for 实际上会调用 customer_posts_path 或 vendor_posts_path,而不是 callind profile_posts_path。

因为我想要像 '/foo'、'/bar' 这样的 URL,其中 foobar 是用户名,所以我编写了这样的路由:

resources :profiles, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i } do
    resources :posts
end

resources :customers, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i } do
    resources :posts
end

resources :vendors, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i } do
    resources :posts
end

这样,所有对“/foo”的请求都将由 ProfilesController 处理(它是列表中的第一个),并且将生成路径帮助器,以便 form_for 可以工作。

但是,即使它有效,这也远非理想。有明显的重复。如果我需要添加另一个嵌套资源,我将不得不添加它三次。

所以我这样重构它(我知道这很可怕,但它确实有效):

profile_block = Proc.new do
    resources :posts
end
resources :profiles, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i }, &profile_block
resources :customer, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i }, &profile_block
resources :vendor, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i }, &profile_block

但这仍然很可怕。我真正想要的是 as 参数是一个数组,这样我就可以做到:

resources :profiles, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i }, as: [ 'profiles', 'customers', 'vendors' ] do
    ...
end

是否有可能实现类似的目标?一切都将映射到同一个控制器。并且没有重复。无需调用 resourcesmatch 或其他任何东西即可创建命名路由的任何方式...

提前致谢

编辑: 在不久的将来,帖子和个人资料之间的关系可能会变得多态。所以 AJcodex 提出的最后一个解决方案会失效。

我觉得这很令人沮丧,我可能会为下一个 Rails 请求这个功能

【问题讨论】:

    标签: ruby-on-rails ruby routes nested-resources named-routing


    【解决方案1】:

    一些选项:

    1. 使用符号form_for([:profile, @post]) do |f|

    2. 别名其他方法。见这个添加路线: How to define own routing helpers in rails 3?

      alias_method :customers_path, :profiles_path
      
    3. 遍历路线中的符号

    在 routes.rb 中

    [ :profiles, :customers, :vendors ].each do |name|
      resources name, path: '/', constraints: { id: /[A-Z0-9\-\+\.]+/i }, as: name do
        resources :posts
      end
    end
    

    您应该考虑使用客户端框架,因为这样您就可以将面向客户端的路由与 API 路由分开。与服务器的 RESTful 请求,用户的虚 URL。

    编辑:

    您是否有理由需要为客户和供应商发送帖子的路线?让配置文件控制器处理所有帖子。一起摆脱供应商和客户喜欢的 url。

    根据是客户还是供应商,如有必要,呈现不同的视图。

    编辑 2:

    手工操作:

    <%= form_for @post, as: :post, url: profile_path(@customer, @post) do |f| %>
      ...
    <% end %>
    

    【讨论】:

    • 3 号肯定比我的“可怕”解决方案更优雅。但是,它仍然会产生很多未定义的路线。我可能会利用这个作为最后的机会。我先试试其他的:)
    • 帖子由 PostsController 处理:P。我不想拥有 CustomerController 或 VendorController,但我仍然需要 STI,因为客户和供应商有很多共同的字段,并且每个字段都有一些独特的字段。我什至不会使用路径助手。问题是 form_for 和 link_to 将使用 fancy 路径助手,而我想将 profile_path 用于所有内容
    • 好的,我承认这将是一个很好的解决方案,我很想将其标记为已接受的答案。但是我只记得帖子和个人资料之间的关系将来可能会变得多态(帖子可能会写在个人资料以外的资源上)。那会破坏你的解决方案。我将编辑问题以添加此详细信息。但是,如果没有其他答案会弹出,我会接受你的答案,作为 谢谢 :)
    • 听起来你可以使用 Concern 来发布帖子,使用 resource :profiles 来获取路线,而这两者永远不会混合使用。祝你好运!
    猜你喜欢
    • 2012-04-22
    • 1970-01-01
    • 2015-11-28
    • 2016-09-24
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-30
    相关资源
    最近更新 更多