Получить маршрут для базового класса класса STI в Rails

Скажем, у меня есть приложение для рельсов с тремя моделями, Person, Place и Thing. Скажем, Thing использует однонаправленное наследование таблицы, поэтому есть подклассы FancyThing и ScaryThing. Тогда есть маршруты, определенные с помощью map.resources :people, :places, :things. Таким образом, нет контроллеров для FancyThings и ScaryThings, ThingsController обрабатывает любой тип.

Теперь скажите, что мне нужно иметь код, который показывает список чего-либо, имеет ссылки на них. Если у меня есть этот код, на мой взгляд:

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

Если элемент является Person или Place, это отлично работает, polymorphic_path заботится о создании правильного маршрута. Но если элемент FancyThing или ScaryThing, это взрывается, потому что он попытается использовать fancy_thing_path, для которого нет маршрута. Я хочу как-то использовать thing_path. В идеале был бы метод Thing и/или его подклассов, который каким-то образом указывает, что подклассы должны использовать базовый класс для генерации маршрута. Есть ли элегантное решение для этого?

Ответ 1

Это сделает трюк:

<% @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.

Ответ 2

Попробуйте использовать

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

Ответ 3

У вас нет правильного ответа, но по крайней мере я могу справиться с этой проблемой, используя код, не содержащий DRY:

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

Надеюсь, что проблема скоро будет исправлена, так как я хочу, чтобы fancy_things управлял только: контроллером вещей. Используя эти маршруты, вы закончите с URL-адресами, например:/fancy_things/1, тогда как вы, возможно, захотите/things/1