【发布时间】: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,其中 foo 和 bar 是用户名,所以我编写了这样的路由:
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
是否有可能实现类似的目标?一切都将映射到同一个控制器。并且没有重复。无需调用 resources 或 match 或其他任何东西即可创建命名路由的任何方式...
提前致谢
编辑: 在不久的将来,帖子和个人资料之间的关系可能会变得多态。所以 AJcodex 提出的最后一个解决方案会失效。
我觉得这很令人沮丧,我可能会为下一个 Rails 请求这个功能
【问题讨论】:
标签: ruby-on-rails ruby routes nested-resources named-routing