Rails STI 和多级继承查询
Rails STI and multi-level inheritance queries
在我的数据库中,我有一个 table people
,我正在使用单个 table 继承,这些 classes:
class Person < ActiveRecord::Base
end
class Member < Person
end
class Business < Member
end
它生成的查询让我很困惑。我想要的是 Member.all
到 return 所有企业以及会员的任何其他子类型。确实如此,但前提是我最近访问了业务 class。我认为这是因为我的 classes 没有在开发模式下缓存(出于明显的原因),但它仍然看起来像 strange/buggy 行为。
这是 rails 中的错误吗?或者它是否按预期工作?在任何一种情况下,有人能想到一个用于开发目的的好的解决方案吗?
默认情况下,Rails 不会急于加载您的 类 开发。尝试更改 config/environments/development.rb
中的以下行:
# Do not eager load code on boot.
config.eager_load = false
至:
# Do eager load code on boot!
config.eager_load = true
这是故意的行为——Autoloading and Reloading Constants explains it pretty well in the section on Autoloading and STI 上的官方 Rails 指南:
…
A way to ensure this works correctly regardless of the order of
execution is to load the leaves of the tree by hand at the bottom of
the file that defines the root class:
# app/models/polygon.rb
class Polygon < ApplicationRecord
end
require_dependency 'square'
Only the leaves that are at least grandchildren need to be loaded this
way. Direct subclasses do not need to be preloaded. If the hierarchy
is deeper, intermediate classes will be autoloaded recursively from
the bottom because their constant will appear in the class definitions
as superclass.
所以在你的情况下,这意味着在你的 Person class.
的末尾放置一个 require_dependency "business"
但是,请注意循环依赖,这可以通过使用 require
而不是 require_dependency
来避免(即使它可能会禁止 Rails 在更改时跟踪和重新加载您的文件made——毕竟,require_dependency
是一个 Rails 内部方法)。
在我的数据库中,我有一个 table people
,我正在使用单个 table 继承,这些 classes:
class Person < ActiveRecord::Base
end
class Member < Person
end
class Business < Member
end
它生成的查询让我很困惑。我想要的是 Member.all
到 return 所有企业以及会员的任何其他子类型。确实如此,但前提是我最近访问了业务 class。我认为这是因为我的 classes 没有在开发模式下缓存(出于明显的原因),但它仍然看起来像 strange/buggy 行为。
这是 rails 中的错误吗?或者它是否按预期工作?在任何一种情况下,有人能想到一个用于开发目的的好的解决方案吗?
默认情况下,Rails 不会急于加载您的 类 开发。尝试更改 config/environments/development.rb
中的以下行:
# Do not eager load code on boot.
config.eager_load = false
至:
# Do eager load code on boot!
config.eager_load = true
这是故意的行为——Autoloading and Reloading Constants explains it pretty well in the section on Autoloading and STI 上的官方 Rails 指南:
…
A way to ensure this works correctly regardless of the order of execution is to load the leaves of the tree by hand at the bottom of the file that defines the root class:
# app/models/polygon.rb class Polygon < ApplicationRecord end require_dependency 'square'
Only the leaves that are at least grandchildren need to be loaded this way. Direct subclasses do not need to be preloaded. If the hierarchy is deeper, intermediate classes will be autoloaded recursively from the bottom because their constant will appear in the class definitions as superclass.
所以在你的情况下,这意味着在你的 Person class.
的末尾放置一个require_dependency "business"
但是,请注意循环依赖,这可以通过使用 require
而不是 require_dependency
来避免(即使它可能会禁止 Rails 在更改时跟踪和重新加载您的文件made——毕竟,require_dependency
是一个 Rails 内部方法)。