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

Rails STI override model_name in parent class for all subclasses

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

def self.model_name
  Mapping.model_name
end

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

class UserMapping < Mapping; end

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

也许还有更好的方法来解决与设置 model_name 无关的 STI 引起的路由问题 - 我乐于接受建议!

提前致谢!

将此放入您的 Mapping class:

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

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

另一种选择是将 superclass 中的 model_name 方法覆盖为 return 自定义 ActiveModel::Name:

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

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

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

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

More in the docs