开发者

Differences in subclasses function between Rails 2 and 3

Let's say I have somethi开发者_如何转开发ng like this

class Major < ActiveRecord::Base
  def self.my_kids
    self.subclasses.collect {|type| type.name}.sort
  end
end

class MinorOne < Major
end

class MinorTwo < Major
end 

In Rails 2.3 I could call Major.my_kids and get back an array of the subclass names, but in Rails 3.0.3 I get back an empty array, unless I load the subclasses first. This seems wrong to me, am I missing something or is this new to Rails 3?


There's no difference that I know of between Rails 2 and 3 concerning the use of the subclasses method. You might have believed it was working previously because the subclasses were already loaded. As Rails load most files dynamically a parent class couldn't know about any class derived from it unless it is defined in the same file. The easiest way to ensure all models are loaded, you can simply call require on all files in the app/models directory:

Dir.glob(RAILS_ROOT + '/app/models/*.rb').each { |file| require file }

One other thing to note is that the subclasses method doesn't work after issuing the reload! command in the Rails console.


The reason why you're getting an empty array in Rails 3 is likely because Rails 3 uses autoloading.

If you open the Rails console and you reference the name of the subclasses, then run your 'subclasses' method on the parent class, you'll see it works. This is because Rails 3 only loads the classes into memory that you've referenced, when you reference them.

The way I ended up forcing my classes to load from a library I created under /lib was with the following code I added into the method that depends on those classes:

# load feature subclasses
my_classes_path = File.expand_path(File.dirname(__FILE__)) + "/my_classes"
if File.directory?(my_classes_path)
  Dir.glob(my_classes_path + "/*.rb").each do |f|
    load f
  end
end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜