如何在Rails中获取子类数组

时间:2010-11-14 11:25:56

标签: ruby reflection inheritance metaprogramming inspect

我有一个模型对象,它是ActiveRecord的子类。此外,使用STI,我定义了此对象的子类,它定义了不同的类型和行为。结构看起来像这样:

class AppModule < ActiveRecord::Base
  belongs_to :app 
end

class AppModuleList < AppModule

end

class AppModuleSearch < AppModule

end

class AppModuleThumbs < AppModule

end

现在,在用户可以选择创建新AppModule的视图中,我希望他们从下拉菜单中进行选择。但是我无法使用subclasses()方法获取AppModule的子类列表:

<% form_for(@app_module) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :type %><br />
    <%= f.select(:type, options_from_collection_for_select(@app_module.subclasses().map{ |c| c.to_s }.sort)) %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>

我明白了:

NoMethodError: undefined method `subclasses' for #<AppModule:0x1036b76d8>

我很感激任何帮助。非常感谢!

2 个答案:

答案 0 :(得分:10)

看起来好像subclasses之类的是recent addition(该方法在不同的时间点存在于不同的类中,但不断被改组并删除;该链接似乎是最早的指出该方法陷入困境)。如果无法升级到最新版本的RoR,您可以编写自己的subclasses并使用Class#inherited填充它(这是RoR的descendents_tracker所做的)。

答案 1 :(得分:5)

AppModule.descendants.map &:name正是您正在寻找的。如:

<% form_for(@app_module) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :type %><br />
    <%= f.select(:type, options_from_collection_for_select(AppModule.descendants.map(&:name).sort)) %>
  </p>
  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>