【问题标题】:Rails STI and multi-level inheritance queriesRails STI 和多级继承查询
【发布时间】:2017-04-29 01:39:54
【问题描述】:

在我的数据库中,我有一个表 people,我正在使用单表继承,这些类:

class Person < ActiveRecord::Base
end

class Member < Person
end

class Business < Member
end

它生成的查询让我感到困惑。我想要的是Member.all 返回所有企业以及任何其他成员子类型。它确实如此,但前提是我最近访问了商务舱。我认为这是因为我的类没有在开发模式下被缓存(原因很明显),但它看起来仍然是奇怪/错误的行为。

这是 Rails 中的错误吗?或者它是否按预期工作?无论哪种情况,任何人都可以为开发目的想出一个好的解决方法吗?

【问题讨论】:

  • 请在每个类中指定继承类型。
  • 桓公子什么意思?

标签: ruby-on-rails ruby activerecord single-table-inheritance


【解决方案1】:

这是有意的行为——Autoloading and Reloading Constants 上的官方 Rails 指南在Autoloading and STI 部分很好地解释了这一点:

一种确保其正常工作的方法,无论顺序如何 执行是在底部手动加载树的叶子 定义根类的文件:

# app/models/polygon.rb
class Polygon < ApplicationRecord
end
require_dependency 'square'

只有至少是孙子的叶子才需要加载这个 方法。直接子类不需要预加载。如果层次结构 更深,中间类将从中递归自动加载 底部,因为它们的常量将出现在类定义中 作为超类。

所以在你的情况下,这意味着在你的 Person 类的末尾放置一个 require_dependency "business"

但是,请注意循环依赖,可以通过使用 require 而不是 require_dependency 来避免循环依赖(尽管它可能会禁止 Rails 在进行更改时跟踪和重新加载文件 - 毕竟,require_dependency 是Rails 内部方法)。

【讨论】:

  • 这是一个有趣的解决方案。下次出现这种情况我会试试的!
【解决方案2】:

默认情况下,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

【讨论】:

  • 好主意!它似乎在我为复制问题而制作的虚拟应用程序中起作用,但并没有解决我在真实应用程序中的所有问题(这可能是由其他原因引起的)。当我有时间正确测试时,我会标记为已接受。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多