我有一个基类通过单表继承继承其他2个.我希望所有子类出于各种原因共享相同的控制器/视图 - 唯一真正的区别在于模型的功能.
但是,当我尝试使用link_to"stuff"时,instance_of_child会收到有关无法找到正确页面的投诉.
我已经尝试搞乱匹配'/ subclass'=> redirect('/ parent'),但这会产生奇怪的链接,没有任何意义.有什么建议?我对rails非常陌生,我承认我对routes.rb的理解仍然有限 - 但是,我并不完全确定这是我应该看的地方.
来自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会在给定对象(此处为car)的类上调用model_name.这将返回一种特殊类型的字符串,用于确定在URL中调用对象的内容.我们在这里所做的只是覆盖Vehicle的子类的model_name方法,因此ActionPack将Car,Truck和Motorcycle子类看作属于父类(Vehicle),因此在URL所在的地方使用父类的命名路由(VehiclesController)产生.这都假设您正在使用Rails资源样式(RESTful)URL.(如果你不是,请做.)
要自己研究model_name调用,请参阅ActionController :: RecordIdentifier#model_name_from_record_or_class方法的Rails源代码.在Rails 2.3中,特殊字符串是ActiveSupport :: ModelName的一个实例,在Rails 3中它是一个ActiveModel :: Name