С http://www.alexreisner.com/code/single-table-inheritance-in-rails:
Если вы когда-либо пытались добавить STI в существующее приложение Rails, вы, вероятно, знаете, что многие из ваших методов link_to и form_for выдают ошибки при добавлении родительского класса.Это связано с тем, что ActionPack просматривает класс объекта, чтобы определить его путь и URL, а вы не сопоставили маршруты для своих новых подклассов.Вы можете добавить маршруты так, хотя я не рекомендую это:
# NOT recommended:
map.resources :cars, :as => :vehicles, :controller => :vehicles
map.resources :trucks, :as => :vehicles, :controller => :vehicles
map.resources :motorcycles, :as => :vehicles, :controller => :vehicles
Это только смягчает определенный симптом.Если мы используем form_for, наши поля формы по-прежнему не будут иметь ожидаемых имен (например: params [: car] [: color] вместо params [: vehicle] [: color]).Вместо этого мы должны атаковать корень проблемы, реализовав метод model_name в нашем родительском классе.Я не видел никакой документации по этой технике, так что она очень неофициальная, но она имеет смысл и прекрасно работает для меня в Rails 2.3 и 3:
def self.inherited(child)
child.instance_eval do
def model_name
Vehicle.model_name
end
end
super
end
Это, вероятно,выглядит странно, поэтому позвольте мне объяснить:
Когда вы вызываете метод генерирования URL (например, link_to ("car", car)), ActionPack вызывает model_name для класса данного объекта (здесь car).Это возвращает специальный тип строки, которая определяет, как объект вызывается в URL.Все, что мы здесь делаем, это переопределение метода model_name для подклассов Vehicle, поэтому ActionPack будет видеть подклассы Car, Truck и Motorcycle как принадлежащие родительскому классу (Vehicle), и, таким образом, будет использовать именованные маршруты родительского класса (VehiclesController) везде, где есть URL-адреса.генерироваться.Все это при условии, что вы используете URL-адреса в стиле ресурсов Rails (RESTful).(Если это не так, пожалуйста.)
Чтобы самостоятельно исследовать вызов model_name, см. Исходный код Rails для метода ActionController :: RecordIdentifier # model_name_from_record_or_class.В Rails 2.3 специальная строка является экземпляром ActiveSupport :: ModelName, в Rails 3 это ActiveModel :: Name