Rails STI覆盖所有子类的父类中的model_name

时间:2015-04-08 23:34:17

标签: ruby-on-rails model routing sti

我在Rails应用程序中使用STI,为了不必为所有子类定义路由,我在每个子类中添加了以下内容:

def self.model_name
  Mapping.model_name
end

在上面的示例中,Mapping是父模型名称。例如:

class UserMapping < Mapping; end

必须将它放在每个子类中并不是很干,所以我正在寻找一种方法在父类中以某种方式设置它,以便从父类继承的每个类自动将模型名称设置为父模型名称。

也许甚至有更好的方法来克服因设置model_name而无法与STI产生的路由问题 - 我对建议持开放态度!

提前致谢!

2 个答案:

答案 0 :(得分:5)

将其放入Mapping班级:

class Mapping < ActiveRecord::Base
  def self.inherited(subclass)
    super
    def subclass.model_name
      superclass.model_name
    end
  end
end

之后,Mapping的所有子类也将继承父级model_name

答案 1 :(得分:0)

另一种选择是重写超类中的model_name方法以返回自定义ActiveModel::Name

class Mapping < ActiveRecord::Base
  def self.model_name
    ActiveModel::Name.new(base_class)
  end
end

默认情况下,model_name将当前类作为第一个参数传递到ActiveModel::Name.new,因此每个子类将根据其类而获得不同的名称。 ActiveRecord模型有一个base_class方法,我们可以用它来获取单表继承层次结构的基础。

如果您愿意,也可以使用完全不同的名称。当您尝试将模型转换为新名称时,这可能会很有用:

class Mapping < ActiveRecord::Base
  def self.model_name
    ActiveModel::Name.new(self, nil, "AnotherMapping")
  end
end

More in the docs