Rails 4 - 带命名空间的 STI

Rails 4 - STI with namespace

如果我有 3 个 class 如下:

class Parent < ActiveRecord::Base
end

class Child < Parent
end

class Another::Child < ::Child
end

所有这 3 个 class 都位于不同的文件夹中。

在 rails 控制台中,Child.first 运行 此查询 SELECT parents.* FROM parents WHERE parents.type IN ('Child') ORDER BY parents.id ASC LIMIT 1

之后,我在 rails 控制台中 运行 Another::Child.first 并生成此查询 SELECT parents.* FROM parents WHERE parents.type IN ('Another::Child') ORDER BY parents.id ASC LIMIT 1

在我 运行 在 rails 控制台中执行命令后,我再次 运行 Child.first 并且查询变为 SELECT parents.* FROM parents WHERE parents.type IN ('Child', 'Another::Child') ORDER BY parents.id ASC LIMIT 1.

这是什么原因?

每当我 运行 Another::Child.first 考虑 Another::ChildChild 的 child class 时,如何始终如一地调用第三个查询?

您描述的行为是由 Rails 模型在开发模式下的延迟加载引起的(开发人员默认情况下禁用预先加载)。在您运行Another::Child.first第一次Another::Child之前还没有加载

您可以通过将 Rails.application.config.eager_load = true 添加到初始化文件来在所有环境中启用预先加载。

在开发中使用预先加载的原因是应用可以(重新)加载得更快。但是,我 运行 在禁用预先加载时遇到很多问题,尤其是对于像您正在使用的 STI 模型。管理起来会很头疼,而且会导致错误,因为开发环境的行为与生产环境不同。由于这些原因,我通常建议设置 eager_load = true.