2

我正在使用 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。

4

3 回答 3

3

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

根据这篇文章,解决此问题的一种方法是执行以下操作:

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

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

于 2013-08-14T18:38:34.330 回答
0

未测试!

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

于 2013-08-14T19:14:46.493 回答
0

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

就像是:

<% Rails.application.eager_load! if Rails.env.development? %>
<% StateDescription.subclasses.each do |state_description| %>
  <li><%= state_description.to_s %> </li>
<% end %>
于 2017-11-13T23:42:25.750 回答