我有一个基类通过Single Table Inheritance继承了另外两个基类。我希望所有子类出于各种原因共享相同的控制器/视图 - 唯一真正的区别在于模型的功能。
然而,当我尝试使用 link_to“stuff”,instance_of_child 时,我抱怨无法找到正确的页面。
我已经尝试搞乱 match'/ subclass'=>重定向('/ parent'),但这会产生奇怪的链接,没有任何意义。有什么建议?我对rails非常陌生,我承认我对routes.rb的理解仍然有限 - 但是,我并不完全确定这是我应该看的地方。
答案 0 :(得分:13)
来自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] 而不是参数[: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 给定物体(这里是汽车)。这回来了 一种特殊类型的字符串 确定调用对象的内容 在URL中。我们在这里所做的就是 重写model_name方法 Vehicle的子类因此ActionPack 将看到汽车,卡车和摩托车 子类属于父类 类(车辆),从而使用 父类的命名路由 (VehiclesController)无论URL在哪里 产生。这都是假设你的 使用Rails资源风格(RESTful) 网址。 (如果你不是,请做。)
调查model_name 自己调用,看看Rails 的源代码 ActionController的:: RecordIdentifier#model_name_from_record_or_class 方法。在Rails 2.3中特别 string是一个实例 Rails 3中的ActiveSupport :: ModelName 它是一个ActiveModel :: Name