mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
ActiveModel::Observing: stop using Observable Ruby module, re-implement notify_observers
`Observable#notify_observers` from Ruby always returns false (which halts ActiveRecord callback chains) and has extra features (like `changed`) that were never used. Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
This commit is contained in:
parent
cf616e4876
commit
c2ca73c9ee
2 changed files with 36 additions and 7 deletions
|
@ -1,4 +1,3 @@
|
|||
require 'observer'
|
||||
require 'singleton'
|
||||
require 'active_support/core_ext/array/wrap'
|
||||
require 'active_support/core_ext/module/aliasing'
|
||||
|
@ -8,10 +7,6 @@ module ActiveModel
|
|||
module Observing
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
extend Observable
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
# Activates the observers assigned. Examples:
|
||||
#
|
||||
|
@ -41,6 +36,22 @@ module ActiveModel
|
|||
observers.each { |o| instantiate_observer(o) }
|
||||
end
|
||||
|
||||
def add_observer(observer)
|
||||
unless observer.respond_to? :update
|
||||
raise ArgumentError, "observer needs to respond to `update'"
|
||||
end
|
||||
@observer_instances ||= []
|
||||
@observer_instances << observer
|
||||
end
|
||||
|
||||
def notify_observers(*arg)
|
||||
if defined? @observer_instances
|
||||
for observer in @observer_instances
|
||||
observer.update(*arg)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
def instantiate_observer(observer) #:nodoc:
|
||||
# string/symbol
|
||||
|
@ -56,7 +67,6 @@ module ActiveModel
|
|||
# Notify observers when the observed class is subclassed.
|
||||
def inherited(subclass)
|
||||
super
|
||||
changed
|
||||
notify_observers :observed_class_inherited, subclass
|
||||
end
|
||||
end
|
||||
|
@ -70,7 +80,6 @@ module ActiveModel
|
|||
# notify_observers(:after_save)
|
||||
# end
|
||||
def notify_observers(method)
|
||||
self.class.changed
|
||||
self.class.notify_observers(method, self)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,14 @@ require 'models/comment'
|
|||
|
||||
class SpecialDeveloper < Developer; end
|
||||
|
||||
class SalaryChecker < ActiveRecord::Observer
|
||||
observe :special_developer
|
||||
|
||||
def before_save(developer)
|
||||
return developer.salary > 80000
|
||||
end
|
||||
end
|
||||
|
||||
class TopicaAuditor < ActiveRecord::Observer
|
||||
observe :topic
|
||||
|
||||
|
@ -159,4 +167,16 @@ class LifecycleTest < ActiveRecord::TestCase
|
|||
assert_equal [ValidatedComment, ValidatedComment, ValidatedCommentObserver], callers,
|
||||
"model callbacks did not fire before observers were notified"
|
||||
end
|
||||
|
||||
test "able to save developer" do
|
||||
SalaryChecker.instance # activate
|
||||
developer = SpecialDeveloper.new :name => 'Roger', :salary => 100000
|
||||
assert developer.save, "developer with normal salary failed to save"
|
||||
end
|
||||
|
||||
test "unable to save developer with low salary" do
|
||||
SalaryChecker.instance # activate
|
||||
developer = SpecialDeveloper.new :name => 'Rookie', :salary => 50000
|
||||
assert !developer.save, "allowed to save a developer with too low salary"
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue