Rails 3 list of all tables as symbols?

Trying to set up an observer to act on all tables. Found this post but
it doesn’t work in Rails 3 (as usual) because :sublcasses is
deprecated:

class AuditObserver < ActiveRecord::Observer

observe ActiveRecord::Base.send(:subclasses)

def after_save(record)
AuditTrail.new(record, “UPDATED”)
end
end

Tried replacing :subclasses with :decendants but it returns the
classes not the tables, and it includes all the fields:

[Person(id: integer, name: text, created_at: datetime, created_by:
text, updated_at: datetime, updated_by: text, email: string),
Member(person_id: integer, club_id: integer, role: text, created_at:
datetime, created_by: text, updated_at: datetime, updated_by: text,
id: integer), Club(id: integer, name: text, created_at: datetime,
created_by: text, updated_at: datetime, updated_by: text), Meeting(id:
integer, club_id: integer, meeting_date: date, meeting_time: time,
topic: text, created_at: datetime, created_by: text, updated_at:
datetime, updated_by: text)]

I need it to return a list like [:person,:member,:club,:meeting]

Any ideas?

Thanks, Lee

On Tuesday, April 26, 2011 10:38:15 AM UTC-6, Lee wrote:

AuditTrail.new(record, "UPDATED")

end
end

From my quick experimentation, I don’t think the deprecation of the
subclasses method is the only problem you’ll have trying to do this.

From my experiment, calling subclasses OR descendants are both
problematic
because (at least in development mode) many of the models won’t have
been
loaded yet (unless you were to require them explicitly beforehand). If a
model hasn’t been loaded, it won’t show up in the list returned by
either
method. On my quick test:

app/models/omni_observer.rb

class OmniObserver < ActiveRecord::Observer
observe ActiveRecord::Base.descendants
Rails.logger.debug ActiveRecord::Base.descendants.inspect
def after_save(object)
Rails.logger.debug “#{object.class.name} instance saved:
#{object.id}”
end
end

I discovered that my logged “list” was always empty: [] even though I
have
several models.

I then manually added a require statement to the top of the file in
order to
manually require my user model:

require ‘user’

Then, it DID work for my user model (and only my user model). Also, just
an
aside, there is no need for this form:

ActiveRecord::Base.send(:descendants)

You can just use: ActiveRecord::Base.descendants

The method is publicly available.

Anyhow, it looks like you’d have to be require-ing all your models at
the
top of the observer code file anyway so that they’d be loaded and be
included in the results of your descendants call. Since you’d
effectively
have a static list anyway, you might as well just manually list them in
your
observe call (unless someone else has a better idea or you want to get
really fancy and do something like Dir[Rails.root.join(“app”, “models”,
“**”, “*”)].each { |f| File.file?(f) ? require(File.basename(f, “.rb”))
:
nil } at the top of your file (I wouldn’t)).

Tried replacing :subclasses with :decendants but it returns the
classes not the tables, and it includes all the fields:

I thought subclasses was supposed to return classes too. The current
(though
deprecated) version does, returning the exact same thing as descendants
in
my rails 3 console session. That aside, I know descendants IS supposed
to
return classes.

[Person(id: integer, name: text, created_at: datetime, created_by:
text, updated_at: datetime, updated_by: text, email: string),
Member(person_id: integer, club_id: integer, role: text, created_at:
datetime, created_by: text, updated_at: datetime, updated_by: text,
id: integer), Club(id: integer, name: text, created_at: datetime,
created_by: text, updated_at: datetime, updated_by: text), Meeting(id:
integer, club_id: integer, meeting_date: date, meeting_time: time,
topic: text, created_at: datetime, created_by: text, updated_at:
datetime, updated_by: text)]

This is just the text-rendering of an array of Class instances.
ActiveRecord
(or some part of rails) defines inspect on model classes to list the
attributes. No “fields” are being “included”. This data array works
perfectly fine as a parameter to the observe method. The observe method
accepts strings (the name of a class) symbols, or a Class instance:

Valid and Equivalent Variations:

observe :your_mom
observe “your_mom”
observe “YourMom”
observe YourMom

YourMom.inspect => YourMom(id: integer, name: string, …)

(http://api.rubyonrails.org/classes/ActiveModel/Observer.html#method-c-observe)

I need it to return a list like [:person,:member,:club,:meeting]

Actually you don’t (see above). Though, like I said above, you’ll
probably
need to hand-code/maintain this list anyway for other reasons.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs