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 [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to