[LRUG] Looping through classes
Ronny Ager-Wick
ronny at ager-wick.com
Wed Mar 13 22:09:14 PDT 2013
I got three private replies, which were all useful, so I'll summarize here for
reference:
On 14/03/13 08:40, Jared Fraser wrote:
> If they're all active record based, you can do ActiveRecord::Base.subclasses
> assuming they're all loaded (like in production)
>
> Jared
I'm not using ActiveRecord, but that subclasses method sure would be useful! I
forgot to mention I use Sinatra, not Rails, and no classes seem to respond to
that method, unfortunately.
On 14/03/13 08:50, George Drummond wrote:
>
> On Thu, Mar 14, 2013 at 12:38 AM, Ronny Ager-Wick <ronny at ager-wick.com
> <mailto:ronny at ager-wick.com>> wrote:
>
> I've been trying to find a way to do this, but I may be searching for
> the wrong terms or something because I get nowhere, even with the help
> of my friend Google.
> I want to loop through the defined classes to see which ons of them
> responds to certain methods.
> The classes I'm trying to find are Ohm Models that have a certain
> attribute defined.
> If I had a collection of classes, I'd probably do something like this:
>
> classes = #get list of all classes
> classes.each { |c|
> # assume it's an Ohm::Model if it responds to :first
> # maybe there's a better way of filtering out only the Ohm models
>
> # Will work if they are all Ohm::Model objects, wont however work if you
> have something that inherits from this class like Car < Ohm::Model
> if c.is_a? Ohm::Model
Alas, that's exactly what I have.
>
> if c.respond_to?(:first) && c.first.respond_to?(:updated_at)
> # convert the timestamp of all records in this model.
> end
> end
>
> The end objective is to convert the timestamp from the old way they used
> to store it (Ohm-contrib 0.*) which looks like this "2011-02-25 21:54:06
> UTC", and the new way, which are UNIX timestamps.
> I could always just make a list of the models manually and loop through
> them, but I want to make a reusable script that others can benefit from
> as well.
>
>
> A better approach may be to fork the gem this is in and rewrite the methods
> that return a UTC date and have a conditional to return the unix timestamp?
Now that is a really good idea! I'll see what I can do with that. I was
thinking of running my conversion before upgrading Ohm and Ohm-contrib,
because after upgrade, I can't even access any of the records:
$ irb -r ./init.rb
irb(main):001:0> Person[1]
NoMethodError: undefined method `2011-02-25 21:52:26 UTC=' for :Person
from /home/user/app/current/vendor/ohm-1.2.0/lib/ohm.rb:1380:in `block in
update_attributes'
from /home/user/app/current/vendor/ohm-1.2.0/lib/ohm.rb:1380:in `each'
from /home/user/app/current/vendor/ohm-1.2.0/lib/ohm.rb:1380:in
`update_attributes'
from /home/user/app/current/vendor/ohm-1.2.0/lib/ohm.rb:1142:in `load!'
from /home/user/app/current/vendor/ohm-1.2.0/lib/ohm.rb:746:in `[]'
from /home/user/app/current/vendor/ohm-contrib-1.2/lib/ohm/slug.rb:9:in `[]'
from (irb):1
from /usr/bin/irb:12:in `<main>'
irb(main):002:0>
It would be a good idea to patch the new version to actually understand old
data! Or in worst case, patch the old version to be able to write new data.
On 14/03/13 08:56, Andrew McDonough wrote:
> Assuming all the classes you want to find inherit from Ohm::Model, you could
> just do:
>
> Ohm::Model.subclasses
>
> Andrew
Yes they do, but I don't have that handy subclasses method. However after
consulting with my knowledgeable friend Google, I found one (
https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.ruby/DoEsfO9EapY
<https://groups.google.com/forum/?fromgroups=#%21topic/comp.lang.ruby/DoEsfO9EapY>)
that I improved a little to remove the class (Ohm::Model in my case) itself:
https://gist.github.com/agerwick/5158730
So now I can simply do:
class Class
def subclasses
class_hash = {}
ObjectSpace.each_object do |obj|
if Class == obj.class
# remove first item from ancestors, which is the class itself - it's wrong to
say a class is a subclass of itself
if obj.ancestors[1..-1].include? self
class_hash[obj] = true
end
end
end
class_hash.keys
end
end
Ohm::Model.subclasses.each do |c|
if c.new.respond_to?(:created_at)
# deal with it
end
c.new.respond_to?(:updated_at)
# deal with it
end
end
Thanks for the great response everybody!
Ronny.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20130314/7b8637c1/attachment-0003.html>
More information about the Chat
mailing list