>我有一个配置文件模型,该模型由客户和供应商模型继承。配置文件has_many :p osts。
当我这样做时
form_for [ @profile, @post ] do |f|
form_for实际上不会调用profile_posts_path,而是调用customer_posts_path或vendor_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"的所有请求都将由配置文件控制器(它是列表中的第一个(处理,并将生成路径帮助程序,以便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提出的最后一个解决方案将中断。
我觉得这很令人沮丧,我可能会为下一个轨道请求此功能
一些选项:
-
使用符号
form_for([:profile, @post]) do |f|
别名 其他方法。有关添加路由的信息,请参阅以下内容:如何在轨道 3 中定义自己的路由助手?
alias_method :customers_path, :profiles_path
循环访问路由中的符号
在路线中.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 %>