我有一个Profile模型,它由Customer和Vendor模型继承。 个人档案has_many:帖子。
当我这样做时
form_for [ @profile, @post ] do |f|
form_for将实际调用customer_posts_path或vendor_posts_path而不是callind profile_posts_path。
由于我想拥有像'/ foo','/ bar'这样的网址,其中 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
是否有可能实现类似的目标?一切都将映射到同一个控制器。行动中没有重复。任何创建命名路由的方法,无需调用资源或匹配或其他任何内容......
提前致谢
修改 帖子和个人资料之间的关系在不久的将来可能会变得多态。因此,AJcodex提出的最后解决方案将会破裂。
我发现这令人沮丧,我可能会为下一个轨道请求此功能
答案 0 :(得分:1)
一些选项:
使用符号form_for([:profile, @post]) do |f|
别名其他方法。看到这个添加路线: How to define own routing helpers in rails 3?
alias_method :customers_path, :profiles_path
迭代路线中的符号
在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。
修改强>
您是否有理由要求客户和供应商发布帖子?让配置文件控制器处理所有帖子。摆脱供应商和客户喜欢的网址。
根据客户或供应商的不同,如有必要,请呈现不同的视图。
编辑2:
手工完成:
<%= form_for @post, as: :post, url: profile_path(@customer, @post) do |f| %>
...
<% end %>