aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activemodel/lib')
-rw-r--r--activemodel/lib/active_model.rb17
-rw-r--r--activemodel/lib/active_model/base.rb4
-rw-r--r--activemodel/lib/active_model/callbacks.rb5
-rw-r--r--activemodel/lib/active_model/observing.rb100
-rw-r--r--activemodel/lib/active_model/validations.rb4
5 files changed, 130 insertions, 0 deletions
diff --git a/activemodel/lib/active_model.rb b/activemodel/lib/active_model.rb
new file mode 100644
index 0000000000..369c7fed33
--- /dev/null
+++ b/activemodel/lib/active_model.rb
@@ -0,0 +1,17 @@
+$LOAD_PATH << File.join(File.dirname(__FILE__), '..', '..', 'activesupport', 'lib')
+
+# premature optimization?
+require 'active_support/inflector'
+require 'active_support/core_ext/string/inflections'
+String.send :include, ActiveSupport::CoreExtensions::String::Inflections
+
+require 'active_model/base'
+require 'active_model/observing'
+require 'active_model/callbacks'
+require 'active_model/validations'
+
+ActiveModel::Base.class_eval do
+ include ActiveModel::Observing
+ include ActiveModel::Callbacks
+ include ActiveModel::Validations
+end \ No newline at end of file
diff --git a/activemodel/lib/active_model/base.rb b/activemodel/lib/active_model/base.rb
new file mode 100644
index 0000000000..1141156da4
--- /dev/null
+++ b/activemodel/lib/active_model/base.rb
@@ -0,0 +1,4 @@
+module ActiveModel
+ class Base
+ end
+end \ No newline at end of file
diff --git a/activemodel/lib/active_model/callbacks.rb b/activemodel/lib/active_model/callbacks.rb
new file mode 100644
index 0000000000..0114fc386b
--- /dev/null
+++ b/activemodel/lib/active_model/callbacks.rb
@@ -0,0 +1,5 @@
+module ActiveModel
+ module Callbacks
+
+ end
+end \ No newline at end of file
diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb
new file mode 100644
index 0000000000..db758f5185
--- /dev/null
+++ b/activemodel/lib/active_model/observing.rb
@@ -0,0 +1,100 @@
+require 'observer'
+
+module ActiveModel
+ module Observing
+ module ClassMethods
+ def observers
+ @observers ||= []
+ end
+
+ def observers=(*values)
+ @observers = values.flatten
+ end
+
+ def instantiate_observers
+ observers.each { |o| instantiate_observer(o) }
+ end
+
+ protected
+ def instantiate_observer(observer)
+ # string/symbol
+ if observer.respond_to?(:to_sym)
+ observer = observer.to_s.camelize.constantize.instance
+ elsif observer.respond_to?(:instance)
+ observer.instance
+ else
+ raise ArgumentError, "#{observer} must be a lowercase, underscored class name (or an instance of the class itself) responding to the instance method. Example: Person.observers = :big_brother # calls BigBrother.instance"
+ end
+ end
+
+ # Notify observers when the observed class is subclassed.
+ def inherited(subclass)
+ super
+ changed
+ notify_observers :observed_class_inherited, subclass
+ end
+ end
+
+ def self.included(receiver)
+ receiver.extend Observable, ClassMethods
+ end
+ end
+
+ class Observer
+ include Singleton
+ attr_writer :observed_classes
+
+ class << self
+ attr_accessor :models
+ # Attaches the observer to the supplied model classes.
+ def observe(*models)
+ @models = models.flatten
+ @models.collect! { |model| model.respond_to?(:to_sym) ? model.to_s.camelize.constantize : model }
+ end
+
+ def observed_class_name
+ @observed_class_name ||=
+ if guessed_name = name.scan(/(.*)Observer/)[0]
+ @observed_class_name = guessed_name[0]
+ end
+ end
+
+ # The class observed by default is inferred from the observer's class name:
+ # assert_equal [Person], PersonObserver.observed_class
+ def observed_class
+ if observed_class_name
+ observed_class_name.constantize
+ else
+ nil
+ end
+ end
+ end
+
+ # Start observing the declared classes and their subclasses.
+ def initialize
+ self.observed_classes = self.class.models if self.class.models
+ observed_classes.each { |klass| add_observer! klass }
+ end
+
+ # Send observed_method(object) if the method exists.
+ def update(observed_method, object) #:nodoc:
+ send(observed_method, object) if respond_to?(observed_method)
+ end
+
+ # Special method sent by the observed class when it is inherited.
+ # Passes the new subclass.
+ def observed_class_inherited(subclass) #:nodoc:
+ self.class.observe(observed_classes + [subclass])
+ add_observer!(subclass)
+ end
+
+ protected
+ def observed_classes
+ @observed_classes ||= [self.class.observed_class]
+ end
+
+ def add_observer!(klass)
+ klass.add_observer(self)
+ end
+ end
+end \ No newline at end of file
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
new file mode 100644
index 0000000000..e3f6584e2b
--- /dev/null
+++ b/activemodel/lib/active_model/validations.rb
@@ -0,0 +1,4 @@
+module ActiveModel
+ module Validations
+ end
+end \ No newline at end of file