views:

53

answers:

2

I'm trying to have a rails model observe another object (which acts as a subject). I saw that there is an update method (which has different semantics) in ActiveRecord::Base, but in order to use the Observable module, I need to implement an update method in my model so that I can be notified of changes to the subject.

Any thoughts on how this could be achieved?

+1  A: 

You probably want to use a regular Observer which will receive event callbacks when something happens to the observed model.

Why do you need to encapsulate your observer functionality into another model?

You're better off putting the events/callbacks in your observer and calling any needed functionality as a helper method on the other model instead of making your model an observer.

EDIT: Adding example code

class User < ActiveRecord::Base
end

class UserObserver < ActiveRecord::Observer
  observe :user

  def after_save(user)
    MyHelperClass.do_some_stuff_for_user(user)
  end
end

class MyHelperClass
  def self.do_some_stuff_for_user(user)
    puts "OMG I just found out #{user.name} was saved so I can do stuff"
  end
end
Winfield
Actually, the object that is being observed is *not* a model, otherwise I would have used `ActiveRecord::Observer`.About the helper methods, could you please elaborate? I am a rails noob :)
rmk
Added an example. This shows a helper method being called on another class to do something with a User object whenever the User object changes.
Winfield
Ok, but I need to observe an object that is *not a model*...
rmk
Can you explain the problem you're trying to solve at a higher level?
Winfield
Yes...So I have a daemon running in `lib/` that retrieves data from the underlying system. Then, it has to push the data into the rails database. It can do this using the Rails ORM. So, I want to structure this as follows:1. The daemon acts as a subject and just sends out notifications saying it got some data from the system.2. There is a separate observer that will respond to this notification by updating/adding new data to the rails model. So, the model is actually the observer. `ActiveRecord::Observer` is for the case when the model is the subject (i.e., providing notifications).
rmk
It sounds like your utility class reading external data and creating models in your system should just use the models directly to import the data into your database?
Winfield
I guess that's a solution. But it would be nicer if all the model-related manipulation could occur within the model itself...
rmk
A: 

It appears that you can override the default update that comes with ActiveRecord, so that it can receive notifications from subjects (assuming you have mixed in Observable). The procedure for doing something like this is in the book "Pro ActiveRecord" published by APress (Chap. 5, "Bonus Features").

It involves the use of alias_method / alias_method_chain with some metaprogramming involved...

I haven't tried this out personally yet, but just leaving a note here in case anyone else is intested.

rmk