On Tuesday, April 26, 2011 10:38:15 AM UTC-6, Lee wrote:>
> 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
>
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.
>
> Any ideas?
>
> Thanks, Lee
>
>
--
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-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.