Ruby on Rails STI场景下如何获取基类Mammal的实例
解决STI子类实例跳转至父类控制器的问题
核心思路
Rails的STI机制会根据模型的type字段自动实例化子类,且默认使用子类对应的路由(比如Cat实例会指向cats#show)。你的需求是让Cat/Dog实例都使用mammals控制器,无需在控制器里判断实例类型,最优雅的方式是修改父类Mammal的路由相关配置,让子类继承父类的路由规则。
解决方案:重写Mammal模型的路由标识方法
在Mammal模型中添加以下代码,统一子类的路由指向:
class Mammal < Pet # 指定路由集合名称为mammals def self.route_key 'mammals' end # 统一模型名称标识为Mammal def self.model_name ActiveModel::Name.new(self, nil, 'Mammal') end end
添加后,无论是Cat还是Dog实例,调用redirect_to时都会自动生成指向mammals控制器的路由(比如mammal_path(cat_instance)),无需在控制器中做类型判断。
为什么不要强行获取Mammal实例
STI的设计初衷就是根据type字段返回对应的子类实例,Mammal.find(id)必然会返回Cat/Dog实例,这是Rails的默认行为,强行修改这个逻辑会破坏STI的封装性,反而引入更多问题。
内容的提问来源于stack exchange,提问作者Matthias Benjamin Schönborn
相关产品推荐
相关产品推荐

