Skip to content

Instantly share code, notes, and snippets.

@whereisciao
Forked from outoftime/observing.rb
Created February 10, 2011 15:34
Show Gist options
  • Save whereisciao/820720 to your computer and use it in GitHub Desktop.
Save whereisciao/820720 to your computer and use it in GitHub Desktop.
Mongoid Observer using ActiveModel.
require "#{RAILS_ROOT}/lib/mongoid/lib/observing.rb"
# Initializer for Observers
User.observers = :user_observer
User.instantiate_observers
# The preferred syntax, similar to AR's setup
# Mongoid.configure do |config|
# config.observers = :user_observer
# end
module Mongoid
module Observing
CALLBACKS = [
:before_create, :before_destroy, :before_save, :before_update,
:before_validation, :after_create, :after_destroy, :after_save,
:after_update, :after_validation
]
def self.included(base)
base.module_eval { include ActiveModel::Observing }
CALLBACKS.each do |callback|
callback_method = :"notify_observers_#{callback}"
base.module_eval <<-RUBY, __FILE__, __LINE__+1
#{callback}(#{callback_method.inspect})
def #{callback_method}(&block)
notify_observers(#{callback.inspect}, &block)
end
private #{callback_method.inspect}
RUBY
end
end
end
end
require 'carrierwave/orm/mongoid'
class User
include Mongoid::Document
include Mongoid::Timestamps
include Mongoid::Observing
field :name
field :username
end
class UserObserver < ActiveModel::Observer
def after_validation(user)
puts "User Observer After Validation"
end
end
@fzxu
Copy link

fzxu commented Mar 6, 2011

There is the problem. the observer for user must be named to 'user_observer' which makes no sense for registration.

@whereisciao
Copy link
Author

Try adding the line "observe :user" to the observer class. If ActiveModel can't infer the model, the observer does not know which class to watch. The source code works very simliar to the directions for ActiveRecord, http://api.rubyonrails.org/classes/ActiveRecord/Observer.html.

@roman
Copy link

roman commented Mar 16, 2011

Why you are not using the ActiveModel observer module?

@whereisciao
Copy link
Author

I'm not following. Isn't ActiveModel::Observing called from observing.rb at line 10?

@cgriego
Copy link

cgriego commented Mar 20, 2011

If you upgrade to Mongoid master then you'll get core support for observers. Add your observers to Mongoid.observers and make them inherit from Mongoid::Observer.

@angelim
Copy link

angelim commented May 5, 2011

Got it to work with cgriego's tips:

  • upgrade mongoid gem to master
  • create an initializer or equivalent to load the observers: Mongoid.observers << :user_observer
  • generate the observer: rails g observer user
  • implement observer class "user_observer" and make it inherit from Mongoid::Observer (the generator will set this up for you)

@gawin
Copy link

gawin commented May 24, 2011

My observer callbacks were called twice. Before and after the original model validation.

Fixed it by removing the explicit callback in the module eval, which causes the observer callback only to trigger after the orignal model callback.

https://gist.github.com/988791

@angelim
Copy link

angelim commented May 24, 2011

No luck using the core support for observers officially added in Mongoid by @cgriego?

@gawin
Copy link

gawin commented May 25, 2011

@angelim, works well with the Mongoid::Observer in master, however our production env isn't upgraded to Mongoid >= 2.0.0 yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment