Hi,
I have this class:
class MoldItem < ActiveRecord::Base
self.abstract_class = true
end
And then I have a (currenly unspecified) number of classes such as
these:
class StringMoldItem < MoldItem
end
class LinkMoldItem < MoldItem
end
I would like to add a class method to MoldItem that will return all of
its subclasses. In the above example, this method would return the
Array [StringMoldItem, LinkMoldItem].
I have been able to write this method in several ways that are
successful using script/console. But as soon as I try to use the
method within my browser (i.e. calling it in a controller) I get
unexpected results.
Option 1:
def self.subklasses(direct = false)
#ensure files are loaded by rails
Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file|
require
file }
classes = []
if direct
ObjectSpace.each_object(Class) do |c|
next unless c.superclass == self
classes << c
end
else
ObjectSpace.each_object(Class) do |c|
next unless c.ancestors.include?(self) and (c != self)
classes << c
end
end
classes
end
Option 2:
def self.subklasses
Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file|
require
file }
@@subclasses[MoldItem]
end
Option 3:
def self.inherited other
super if defined? super
ensure
( @subclasses ||= [] ).push(other).uniq!
end
def self.subklasses
Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file|
require
file }
@subclasses ||= []
@subclasses.inject( [] ) do |list, subclass|
list.push(subclass, *subclass.subklasses)
end
end
Results: when I run MoldItem.subklasses using script/console, I get
the correct result for all three options. When I run it from a
controller (by visiting a page of my website), the first request after
starting mongrel works. However, every subsequent request will return
[] or nil (depending on the option).
I think the problem is a conflict between this line:
Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file|
require file }
(which is meant to ensure that the subclasses such as StringMoldItem
and LinkMoldItem exist) and rails'' fancy way of requiring source files
(would that be ActiveSupport::Dependencies#load_missing_constant?).
Do you have any suggestions for how I can dynamically return a list of
the subclasses of MoldItem?
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
On 14 Sep 2008, at 21:05, DyingToLearn wrote:> > I think the problem is a conflict between this line: > Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file| require file } > (which is meant to ensure that the subclasses such as StringMoldItem > and LinkMoldItem exist) and rails'' fancy way of requiring source files > (would that be ActiveSupport::Dependencies#load_missing_constant?). >Probably. Using require_dependency instead require might help. Fred> Do you have any suggestions for how I can dynamically return a list of > the subclasses of MoldItem? > >--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks!
I just needed to change this:
Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file|
require file }
to this:
Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each { |file|
require_dependency file }
Now I just need to think of some way to not require reading the entire
directory contents every time the method is called :)
Paul
Frederick Cheung wrote:> On 14 Sep 2008, at 21:05, DyingToLearn wrote:
> >
> > I think the problem is a conflict between this line:
> > Dir.glob(RAILS_ROOT + ''/app/models/*.rb'').each {
|file| require file }
> > (which is meant to ensure that the subclasses such as StringMoldItem
> > and LinkMoldItem exist) and rails'' fancy way of requiring
source files
> > (would that be ActiveSupport::Dependencies#load_missing_constant?).
> >
> Probably. Using require_dependency instead require might help.
>
> Fred
> > Do you have any suggestions for how I can dynamically return a list of
> > the subclasses of MoldItem?
> > >
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---