【问题标题】:Rails STI, subclasses don't show up unless used?Rails STI,除非使用,否则子类不会显示?
【发布时间】:2017-11-14 07:42:25
【问题描述】:

我正在使用 Rails STI 对复杂域进行建模。在一个视图中,我列出了所有子类:

> <% StateDescription.subclasses.each do |state_description| %>   <li>
> <%= state_description.to_s %> </li> <% end %>

旨在最终使子类的每个标签成为指向该子类实例的单个“索引”页面的链接。

这使我不必自己拥有所有可能子类的列表(如果我添加更多,以后再更新它)。

但是,我注意到只有我实际从数据库中加载的那些子类显示在列表中。如果我说 StateDescription.all,那么所有现有的子类都会出现(但没有一个没有实例)。如果我改为询问所有特定子类,那么只会显示该子类。

我想这是我听说过的“延迟加载”的一部分。是吗?问题似乎是,如果我不从数据库中获取特定的“类型”,即使我有它的模型,它也可能不存在?

有没有办法解决这个问题,还是我注定要为我创建的每个子类写一个链接?

编辑:

在控制台上,如果我键入

StateDescription.subclasses.count

我得到 0。

如果我然后执行 StateDescription.all 和 THEN StateDescription.subclasses.count,我得到 14。

【问题讨论】:

  • 试试StateDescription.descendants,看看会不会有什么不同。我不熟悉该方法,因此无法直接回答您的问题,但您对延迟加载的想法可能是正确的。
  • .descendants 具有完全相同的行为,遗憾的是。
  • 是的,我在发布后意识到#subclasses 实际上使用了#descendants 方法,所以这是有道理的。忽略那个。我的回答有帮助吗?

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


【解决方案1】:

在进行了一些挖掘之后,您关于由于延迟加载而未显示子类的假设似乎是正确的。由于您在开发模式下运行应用程序,因此在专门调用它们之前不会加载所有类。在生产中,您不会遇到这个问题,因为所有内容都是一次加载并缓存的。

根据this post,解决此问题的一种方法是执行以下操作:

[Subclass1, Subclass2, Subclass3] if Rails.env == 'development'

您可以将它放在控制器的顶部,以便它在控制器类加载的瞬间加载,或者在前置过滤器中。

【讨论】:

  • 你说得对,如果我把东西投入生产,它就是固定的!也感谢您的工作。
【解决方案2】:

未测试!

StateDescription.select("distinct type").map { |sd|  Kernel.const_get(sd.type) }

【讨论】:

  • 唯一的问题是,如果StateDescription 的任何子类尚未在数据库中创建记录,它们仍然不会显示在此处。
【解决方案3】:

最简单的方法是 eager_load! 正在开发中。

类似:

<% Rails.application.eager_load! if Rails.env.development? %>
<% StateDescription.subclasses.each do |state_description| %>
  <li><%= state_description.to_s %> </li>
<% end %>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 2013-01-10
    • 1970-01-01
    • 2017-03-11
    • 1970-01-01
    • 2014-05-28
    相关资源
    最近更新 更多