获取Rails中STI类基类的路线

问题描述 投票:0回答:4

假设我有一个包含 3 个模型的 Rails 应用程序:人、地点和事物。 假设 Thing 使用单表继承,因此有 FancyThing 和 ScaryThing 子类。 然后是用

map.resources :people, :places, :things
定义的路线。 因此,FancyThings 和 ScaryThings 没有控制器,ThingsController 可以处理任一类型。

现在假设我需要有代码来显示所有具有链接的内容的列表。 如果我认为有这段代码:

<% @items.each do |item| %>
  <%= link_to item.name, item %>
<% end %>

如果项目是一个人或一个地方,这工作正常,

polymorphic_path
负责生成正确的路线。 但如果 item 是 FancyThing 或 ScaryThing,就会崩溃,因为它会尝试使用
fancy_thing_path
,而这是没有路径的。 我想以某种方式让它使用
thing_path
。 理想情况下,Thing 和/或其子类上应该有一个方法,以某种方式指示子类应该使用基类来生成路由。 有一个优雅的解决方案吗?

ruby-on-rails ruby
4个回答
12
投票

这就能解决问题:

<% @items.map {|i| if i.class < Thing then i.becomes(Thing) else i end}.each do |item| %>
  <%= link_to item.name, item %>
<% end %>

这使用 ActiveRecord 函数“成为”将 Thing 的所有子类“向上转换”到 Thing 基类。


8
投票

尝试使用

map.resources :things
map.resources :fancy_things, :controller => 'things'
map.resources :scary_things, :controller => 'things'

0
投票

没有正确的答案,但至少我可以使用非 DRY 代码来处理这个问题:

map.resources :things, :has_many => :stuffs map.resources :fancy_things, :controller => '东西', :has_many => :stuffs map.resources :scary_things, :controller => 'things', :has_many => :stuffs

希望这个问题能很快在 Edge 中得到纠正,因为我希望看到 fancy_things 仅由 :things 控制器管理。使用这些路由,您将以如下网址结尾:/fancy_things/1,而您可能想要/things/1


0
投票

在路由文件中,您可以通过 Resolve 方法强制子类使用基类路由。 通过这种方式,您不会通过

becomes
调用污染其余代码(控制器、视图等)基础,并将其包含到路由文件中。

    resolve("FancyThing") do |thing|
      thing.becomes(Thing)
    end
    resolve("ScaryThing") do |thing|
      thing.becomes(Thing)
    end
© www.soinside.com 2019 - 2024. All rights reserved.