У меня возникли проблемы с настройкой маршрутизации для удобного использования Single Table Inheritance в моем приложении Ruby on Rails. Я использую Ruby 1.9.2 и Rails 3.0.6. Он находится в разработке, поэтому серверная часть - это SQLite3, на случай, если что-то изменится.
Допустим, у меня есть два продукта, widgets
и sprockets
. Мое приложение отслеживает номера ошибок и заявки на поддержку для обоих продуктов, но сами ошибки и заявки на поддержку хранятся в других системах. Над этими двумя продуктами работают две отдельные команды.
Я реализовал наследование одной таблицы для двух типов записей ошибок, потому что правила проверки номеров ошибок виджетов и номеров звездочек различны (две команды используют разные системы отслеживания ошибок), и есть вероятность, что мне придется добавьте в приложение другие продукты, которые ведут себя по-разному. Использование STI дает мне гибкость для реализации дополнительных методов и свойств по мере необходимости.
Команда виджетов заботится только об информации виджетов, а команда звездочек заботится только об информации звездочек. Есть третья команда, которая должна иметь возможность просматривать информацию как на виджетах, так и на звездочках. Команда виджетов получит доступ к приложению по пути /widgets
, а команда звездочек получит доступ к приложению по пути /sprockets
. Я настроил это в routes.rb
, используя пространства имен:
resources :bugs
namespace "widgets" do
resources :bugs
end
namespace "sprockets" do
resources :bugs
end
Я настроил следующие модели, которые работают, как и ожидалось, когда я запускаю irb и использую WidgetBug.create()
или SprocketBug.create()
:
bug.rb
class Bug < ActiveRecord::Base
end
widget_bug.rb
class WidgetBug < Bug
# Some validation rules
end
sprocket_bug.rb
class SprocketBug < Bug
# Some different validation rules
end
Я использовал scaffolding для создания контроллера и представления объекта ошибки, затем изменил контроллер, чтобы попытаться обобщить его, чтобы он мог использоваться как с ошибками виджетов, так и с ошибками звездочек. Например, метод index
выглядит следующим образом:
def index
# The scaffold code lists all bugs, which is not what we want
# @bugs = Bug.all
# Only return bugs of the subclass we're looking for
@bugs = eval("#{params[:controller].classify}.all")
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @bugs }
end
end
Затем я использовал create()
, чтобы заполнить базу данных несколькими ошибками каждого типа. К сожалению, когда я перехожу к /widgets/bugs
, появляются ошибки для обоих продуктов. После некоторой отладки я определил, что вызов classify возвращает Widgets::Bugs
или Sprockets::Bugs
, поэтому, когда я вызываю все на нем, он работает против суперкласса, а не против подкласса.
Я просмотрел документацию по маршрутизации и провел немало поисков в Google, но я все еще в растерянности относительно того, как я могу изменить маршрутизацию или контроллер для правильной работы. Любая помощь будет принята с благодарностью.