Rails STI, subclasses don't show up unless used?

无人久伴 提交于 2019-12-11 01:09:09

问题


I am using Rails STI to model a complex domain. In a view, I am listing all subclasses with:

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

With the intent to eventually make each label of the subclass a link to the individual "index" page for just instances of that subclass.

This saves me from having to have a list of all possible subclasses myself (and updating it later if I add more).

However, I have noticed that only those subclasses I have actually loaded from the database show up in the list. If I say StateDescription.all, then all existing subclasses show up (but none that have no instances yet). If I instead ask for all of a particular subclass, then only that subclass show up.

I imagine this is part of the "lazy loading" I have heard about. Is it? It SEEMS like the problem is that if I don't grab a particular "type" from the database, even if I have a model for it, it may as well not exist?

Is there a way around this, or am I doomed to have to write out a link for every single subclass I create?

Edit:

On the console, if I type

StateDescription.subclasses.count

I get 0.

If I then do StateDescription.all and THEN StateDescription.subclasses.count, i get 14.


回答1:


After doing some digging, it seems your hypothesis about subclasses not showing up due to lazy loading appears to be correct. Since you're running your application in development mode, all your classes are not loaded until they are specifically called. In production, you would not have this problem since everything is loaded at once and cached.

One way to get around this problem, according to this post, is to do something like this:

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

You could put this at the top of your controller so that it loads the instant the controller classes is loaded, or in a before filter.




回答2:


Not tested!

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




回答3:


The easiest way to do this is eager_load! in development.

Something like:

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


来源:https://stackoverflow.com/questions/18239012/rails-sti-subclasses-dont-show-up-unless-used

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!