Rails STI,子类除非使用否则不显示?

时间:2013-08-14 18:04:00

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

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

3 个答案:

答案 0 :(得分:3)

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

根据this post,解决这个问题的一种方法是做这样的事情:

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

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

答案 1 :(得分:0)

未经测试!

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

答案 2 :(得分:0)

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

类似的东西:

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