diff options
Diffstat (limited to 'activerecord/lib/active_record/model.rb')
-rw-r--r-- | activerecord/lib/active_record/model.rb | 103 |
1 files changed, 71 insertions, 32 deletions
diff --git a/activerecord/lib/active_record/model.rb b/activerecord/lib/active_record/model.rb index 105d1e0e2b..831745856b 100644 --- a/activerecord/lib/active_record/model.rb +++ b/activerecord/lib/active_record/model.rb @@ -1,6 +1,34 @@ require 'active_support/deprecation' +require 'active_support/concern' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/module/attribute_accessors' module ActiveRecord + module Configuration # :nodoc: + # This just abstracts out how we define configuration options in AR. Essentially we + # have mattr_accessors on the ActiveRecord:Model constant that define global defaults. + # Classes that then use AR get class_attributes defined, which means that when they + # are assigned the default will be overridden for that class and subclasses. (Except + # when options[:global] == true, in which case there is one global value always.) + def config_attribute(name, options = {}) + if options[:global] + class_eval <<-CODE, __FILE__, __LINE__ + 1 + def self.#{name}; ActiveRecord::Model.#{name}; end + def #{name}; ActiveRecord::Model.#{name}; end + def self.#{name}=(val); ActiveRecord::Model.#{name} = val; end + CODE + else + options[:instance_writer] ||= false + class_attribute name, options + + singleton_class.class_eval <<-CODE, __FILE__, __LINE__ + 1 + remove_method :#{name} + def #{name}; ActiveRecord::Model.#{name}; end + CODE + end + end + end + # <tt>ActiveRecord::Model</tt> can be included into a class to add Active Record persistence. # This is an alternative to inheriting from <tt>ActiveRecord::Base</tt>. Example: # @@ -9,41 +37,34 @@ module ActiveRecord # end # module Model - module ClassMethods #:nodoc: - include ActiveSupport::Callbacks::ClassMethods - include ActiveModel::Naming - include QueryCache::ClassMethods - include ActiveSupport::Benchmarkable - include ActiveSupport::DescendantsTracker - - include Querying - include Translation - include DynamicMatchers - include CounterCache - include Explain - include ConnectionHandling - end + extend ActiveSupport::Concern + extend ConnectionHandling - def self.included(base) - return if base.singleton_class < ClassMethods + # This allows us to detect an ActiveRecord::Model while it's in the process of being included. + module Tag; end + def self.append_features(base) base.class_eval do - extend ClassMethods - Callbacks::Register.setup(self) - initialize_generated_modules unless self == Base + include Tag + extend Configuration end + + super end - extend ActiveModel::Configuration - extend ActiveModel::Callbacks - extend ActiveModel::MassAssignmentSecurity::ClassMethods - extend ActiveModel::AttributeMethods::ClassMethods - extend Callbacks::Register - extend Explain - extend ConnectionHandling + included do + extend ActiveModel::Naming + extend ActiveSupport::Benchmarkable + extend ActiveSupport::DescendantsTracker + + extend QueryCache::ClassMethods + extend Querying + extend Translation + extend DynamicMatchers + extend Explain + extend ConnectionHandling - def self.extend(*modules) - ClassMethods.send(:include, *modules) + initialize_generated_modules unless self == Base end include Persistence @@ -56,13 +77,22 @@ module ActiveRecord include AttributeAssignment include ActiveModel::Conversion include Validations - include Locking::Optimistic, Locking::Pessimistic + include CounterCache + include Locking::Optimistic + include Locking::Pessimistic include AttributeMethods - include Callbacks, ActiveModel::Observing, Timestamp + include Callbacks + include ActiveModel::Observing + include Timestamp include Associations include ActiveModel::SecurePassword - include AutosaveAssociation, NestedAttributes - include Aggregations, Transactions, Reflection, Serialization, Store + include AutosaveAssociation + include NestedAttributes + include Aggregations + include Transactions + include Reflection + include Serialization + include Store include Core class << self @@ -103,6 +133,15 @@ module ActiveRecord end end + # This hook is where config accessors on Model get defined. + # + # We don't want to just open the Model module and add stuff to it in other files, because + # that would cause Model to load, which causes all sorts of loading order issues. + # + # We need this hook rather than just using the :active_record one, because users of the + # :active_record hook may need to use config options. + ActiveSupport.run_load_hooks(:active_record_config, Model) + # Load Base at this point, because the active_record load hook is run in that file. Base end |