Skip to content
This repository
Browse code

Remove ActiveRecord::Model

In the end I think the pain of implementing this seamlessly was not
worth the gain provided.

The intention was that it would allow plain ruby objects that might not
live in your main application to be subclassed and have persistence
mixed in. But I've decided that the benefit of doing that is not worth
the amount of complexity that the implementation introduced.
  • Loading branch information...
commit 9e4c41c903e8e58721f2c41776a8c60ddba7a0a9 1 parent a27b517
Jon Leighton authored October 26, 2012

Showing 40 changed files with 232 additions and 642 deletions. Show diff stats Hide diff stats

  1. 28  activerecord/CHANGELOG.md
  2. 1  activerecord/lib/active_record.rb
  3. 2  activerecord/lib/active_record/associations/alias_tracker.rb
  4. 2  activerecord/lib/active_record/attribute_methods.rb
  5. 8  activerecord/lib/active_record/attribute_methods/dirty.rb
  6. 9  activerecord/lib/active_record/attribute_methods/read.rb
  7. 16  activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
  8. 46  activerecord/lib/active_record/base.rb
  9. 8  activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
  10. 1  activerecord/lib/active_record/connection_handling.rb
  11. 144  activerecord/lib/active_record/core.rb
  12. 8  activerecord/lib/active_record/explain.rb
  13. 2  activerecord/lib/active_record/fixtures.rb
  14. 41  activerecord/lib/active_record/inheritance.rb
  15. 8  activerecord/lib/active_record/locking/optimistic.rb
  16. 167  activerecord/lib/active_record/model.rb
  17. 47  activerecord/lib/active_record/model_schema.rb
  18. 8  activerecord/lib/active_record/nested_attributes.rb
  19. 11  activerecord/lib/active_record/railtie.rb
  20. 2  activerecord/lib/active_record/relation/finder_methods.rb
  21. 6  activerecord/lib/active_record/relation/predicate_builder.rb
  22. 2  activerecord/lib/active_record/result.rb
  23. 11  activerecord/lib/active_record/serialization.rb
  24. 5  activerecord/lib/active_record/timestamp.rb
  25. 6  activerecord/test/cases/adapter_test.rb
  26. 22  activerecord/test/cases/adapters/mysql/connection_test.rb
  27. 12  activerecord/test/cases/adapters/mysql2/connection_test.rb
  28. 2  activerecord/test/cases/attribute_methods/read_test.rb
  29. 14  activerecord/test/cases/base_test.rb
  30. 4  activerecord/test/cases/connection_adapters/connection_handler_test.rb
  31. 8  activerecord/test/cases/defaults_test.rb
  32. 133  activerecord/test/cases/inclusion_test.rb
  33. 11  activerecord/test/cases/inheritance_test.rb
  34. 4  activerecord/test/cases/multiple_db_test.rb
  35. 18  activerecord/test/cases/pooled_connections_test.rb
  36. 4  activerecord/test/cases/primary_keys_test.rb
  37. 6  activerecord/test/cases/unconnected_test.rb
  38. 35  activerecord/test/models/teapot.rb
  39. 6  activerecord/test/schema/schema.rb
  40. 6  activerecord/test/support/connection.rb
28  activerecord/CHANGELOG.md
Source Rendered
@@ -926,34 +926,6 @@
926 926
 
927 927
     *Aaron Patterson*
928 928
 
929  
-*   Added the `ActiveRecord::Model` module which can be included in a
930  
-    class as an alternative to inheriting from `ActiveRecord::Base`:
931  
-
932  
-        class Post
933  
-          include ActiveRecord::Model
934  
-        end
935  
-
936  
-    Please note:
937  
-
938  
-      * Up until now it has been safe to assume that all AR models are
939  
-        descendants of `ActiveRecord::Base`. This is no longer a safe
940  
-        assumption, but it may transpire that there are areas of the
941  
-        code which still make this assumption. So there may be
942  
-        'teething difficulties' with this feature. (But please do try it
943  
-        and report bugs.)
944  
-
945  
-      * Plugins & libraries etc that add methods to `ActiveRecord::Base`
946  
-        will not be compatible with `ActiveRecord::Model`. Those libraries
947  
-        should add to `ActiveRecord::Model` instead (which is included in
948  
-        `Base`), or better still, avoid monkey-patching AR and instead
949  
-        provide a module that users can include where they need it.
950  
-
951  
-      * To minimise the risk of conflicts with other code, it is
952  
-        advisable to include `ActiveRecord::Model` early in your class
953  
-        definition.
954  
-
955  
-    *Jon Leighton*
956  
-
957 929
 *   PostgreSQL hstore records can be created.
958 930
 
959 931
     *Aaron Patterson*
1  activerecord/lib/active_record.rb
@@ -43,7 +43,6 @@ module ActiveRecord
43 43
   autoload :Integration
44 44
   autoload :Migration
45 45
   autoload :Migrator, 'active_record/migration'
46  
-  autoload :Model
47 46
   autoload :ModelSchema
48 47
   autoload :NestedAttributes
49 48
   autoload :Observer
2  activerecord/lib/active_record/associations/alias_tracker.rb
@@ -8,7 +8,7 @@ class AliasTracker # :nodoc:
8 8
       attr_reader :aliases, :table_joins, :connection
9 9
 
10 10
       # table_joins is an array of arel joins which might conflict with the aliases we assign here
11  
-      def initialize(connection = ActiveRecord::Model.connection, table_joins = [])
  11
+      def initialize(connection = Base.connection, table_joins = [])
12 12
         @aliases     = Hash.new { |h,k| h[k] = initial_count_for(k) }
13 13
         @table_joins = table_joins
14 14
         @connection  = connection
2  activerecord/lib/active_record/attribute_methods.rb
@@ -59,7 +59,7 @@ def instance_method_already_implemented?(method_name)
59 59
           raise DangerousAttributeError, "#{method_name} is defined by ActiveRecord"
60 60
         end
61 61
 
62  
-        if [Base, Model].include?(active_record_super)
  62
+        if superclass == Base
63 63
           super
64 64
         else
65 65
           # If B < A and A defines its own attribute method, then we don't want to overwrite that.
8  activerecord/lib/active_record/attribute_methods/dirty.rb
@@ -2,11 +2,6 @@
2 2
 require 'active_support/deprecation'
3 3
 
4 4
 module ActiveRecord
5  
-  ActiveSupport.on_load(:active_record_config) do
6  
-    mattr_accessor :partial_writes, instance_accessor: false
7  
-    self.partial_writes = true
8  
-  end
9  
-
10 5
   module AttributeMethods
11 6
     module Dirty # :nodoc:
12 7
       extend ActiveSupport::Concern
@@ -18,7 +13,8 @@ module Dirty # :nodoc:
18 13
           raise "You cannot include Dirty after Timestamp"
19 14
         end
20 15
 
21  
-        config_attribute :partial_writes
  16
+        class_attribute :partial_writes, instance_writer: false
  17
+        self.partial_writes = true
22 18
 
23 19
         def self.partial_updates=(v); self.partial_writes = v; end
24 20
         def self.partial_updates?; partial_writes?; end
9  activerecord/lib/active_record/attribute_methods/read.rb
... ...
@@ -1,8 +1,4 @@
1 1
 module ActiveRecord
2  
-  ActiveSupport.on_load(:active_record_config) do
3  
-    mattr_accessor :attribute_types_cached_by_default, instance_accessor: false
4  
-  end
5  
-
6 2
   module AttributeMethods
7 3
     module Read
8 4
       extend ActiveSupport::Concern
@@ -10,7 +6,8 @@ module Read
10 6
       ATTRIBUTE_TYPES_CACHED_BY_DEFAULT = [:datetime, :timestamp, :time, :date]
11 7
 
12 8
       included do
13  
-        config_attribute :attribute_types_cached_by_default
  9
+        class_attribute :attribute_types_cached_by_default, instance_writer: false
  10
+        self.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
14 11
       end
15 12
 
16 13
       module ClassMethods
@@ -79,8 +76,6 @@ def cacheable_column?(column)
79 76
         end
80 77
       end
81 78
 
82  
-      ActiveRecord::Model.attribute_types_cached_by_default = ATTRIBUTE_TYPES_CACHED_BY_DEFAULT
83  
-
84 79
       # Returns the value of the attribute identified by <tt>attr_name</tt> after
85 80
       # it has been typecast (for example, "2004-12-12" in a data column is cast
86 81
       # to a date object, like Date.new(2004, 12, 12)).
16  activerecord/lib/active_record/attribute_methods/time_zone_conversion.rb
... ...
@@ -1,13 +1,4 @@
1  
-
2 1
 module ActiveRecord
3  
-  ActiveSupport.on_load(:active_record_config) do
4  
-    mattr_accessor :time_zone_aware_attributes, instance_accessor: false
5  
-    self.time_zone_aware_attributes = false
6  
-
7  
-    mattr_accessor :skip_time_zone_conversion_for_attributes, instance_accessor: false
8  
-    self.skip_time_zone_conversion_for_attributes = []
9  
-  end
10  
-
11 2
   module AttributeMethods
12 3
     module TimeZoneConversion
13 4
       class Type # :nodoc:
@@ -28,8 +19,11 @@ def type
28 19
       extend ActiveSupport::Concern
29 20
 
30 21
       included do
31  
-        config_attribute :time_zone_aware_attributes, global: true
32  
-        config_attribute :skip_time_zone_conversion_for_attributes
  22
+        mattr_accessor :time_zone_aware_attributes, instance_writer: false
  23
+        self.time_zone_aware_attributes = false
  24
+
  25
+        class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
  26
+        self.skip_time_zone_conversion_for_attributes = []
33 27
       end
34 28
 
35 29
       module ClassMethods
46  activerecord/lib/active_record/base.rb
@@ -321,8 +321,48 @@ module ActiveRecord #:nodoc:
321 321
   # So it's possible to assign a logger to the class through <tt>Base.logger=</tt> which will then be used by all
322 322
   # instances in the current object space.
323 323
   class Base
324  
-    include ActiveRecord::Model
  324
+    extend ActiveModel::Observing::ClassMethods
  325
+    extend ActiveModel::Naming
  326
+
  327
+    extend ActiveSupport::Benchmarkable
  328
+    extend ActiveSupport::DescendantsTracker
  329
+
  330
+    extend ConnectionHandling
  331
+    extend QueryCache::ClassMethods
  332
+    extend Querying
  333
+    extend Translation
  334
+    extend DynamicMatchers
  335
+    extend Explain
  336
+    extend ConnectionHandling
  337
+
  338
+    include Persistence
  339
+    include ReadonlyAttributes
  340
+    include ModelSchema
  341
+    include Inheritance
  342
+    include Scoping
  343
+    include Sanitization
  344
+    include AttributeAssignment
  345
+    include ActiveModel::Conversion
  346
+    include Integration
  347
+    include Validations
  348
+    include CounterCache
  349
+    include Locking::Optimistic
  350
+    include Locking::Pessimistic
  351
+    include AttributeMethods
  352
+    include Callbacks
  353
+    include ActiveModel::Observing
  354
+    include Timestamp
  355
+    include Associations
  356
+    include ActiveModel::SecurePassword
  357
+    include AutosaveAssociation
  358
+    include NestedAttributes
  359
+    include Aggregations
  360
+    include Transactions
  361
+    include Reflection
  362
+    include Serialization
  363
+    include Store
  364
+    include Core
325 365
   end
326  
-end
327 366
 
328  
-ActiveSupport.run_load_hooks(:active_record, ActiveRecord::Model::DeprecationProxy.new)
  367
+  ActiveSupport.run_load_hooks(:active_record, Base)
  368
+end
8  activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -441,11 +441,11 @@ def release(conn)
441 441
       end
442 442
 
443 443
       def new_connection
444  
-        ActiveRecord::Model.send(spec.adapter_method, spec.config)
  444
+        Base.send(spec.adapter_method, spec.config)
445 445
       end
446 446
 
447 447
       def current_connection_id #:nodoc:
448  
-        ActiveRecord::Model.connection_id ||= Thread.current.object_id
  448
+        Base.connection_id ||= Thread.current.object_id
449 449
       end
450 450
 
451 451
       def checkout_new_connection
@@ -567,10 +567,10 @@ def retrieve_connection_pool(klass)
567 567
         class_to_pool[klass] ||= begin
568 568
           until pool = pool_for(klass)
569 569
             klass = klass.superclass
570  
-            break unless klass < ActiveRecord::Tag
  570
+            break unless klass <= Base
571 571
           end
572 572
 
573  
-          class_to_pool[klass] = pool || pool_for(ActiveRecord::Model)
  573
+          class_to_pool[klass] = pool
574 574
         end
575 575
       end
576 576
 
1  activerecord/lib/active_record/connection_handling.rb
... ...
@@ -1,4 +1,3 @@
1  
-
2 1
 module ActiveRecord
3 2
   module ConnectionHandling
4 3
     # Establishes the connection to the database. Accepts a hash as input where
144  activerecord/lib/active_record/core.rb
@@ -4,73 +4,6 @@
4 4
 
5 5
 module ActiveRecord
6 6
   ActiveSupport.on_load(:active_record_config) do
7  
-    ##
8  
-    # :singleton-method:
9  
-    #
10  
-    # Accepts a logger conforming to the interface of Log4r which is then
11  
-    # passed on to any new database connections made and which can be
12  
-    # retrieved on both a class and instance level by calling +logger+.
13  
-    mattr_accessor :logger, instance_accessor: false
14  
-
15  
-    ##
16  
-    # :singleton-method:
17  
-    # Contains the database configuration - as is typically stored in config/database.yml -
18  
-    # as a Hash.
19  
-    #
20  
-    # For example, the following database.yml...
21  
-    #
22  
-    #   development:
23  
-    #     adapter: sqlite3
24  
-    #     database: db/development.sqlite3
25  
-    #
26  
-    #   production:
27  
-    #     adapter: sqlite3
28  
-    #     database: db/production.sqlite3
29  
-    #
30  
-    # ...would result in ActiveRecord::Base.configurations to look like this:
31  
-    #
32  
-    #   {
33  
-    #      'development' => {
34  
-    #         'adapter'  => 'sqlite3',
35  
-    #         'database' => 'db/development.sqlite3'
36  
-    #      },
37  
-    #      'production' => {
38  
-    #         'adapter'  => 'sqlite3',
39  
-    #         'database' => 'db/production.sqlite3'
40  
-    #      }
41  
-    #   }
42  
-    mattr_accessor :configurations, instance_accessor: false
43  
-    self.configurations = {}
44  
-
45  
-    ##
46  
-    # :singleton-method:
47  
-    # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
48  
-    # dates and times from the database. This is set to :utc by default.
49  
-    mattr_accessor :default_timezone, instance_accessor: false
50  
-    self.default_timezone = :utc
51  
-
52  
-    ##
53  
-    # :singleton-method:
54  
-    # Specifies the format to use when dumping the database schema with Rails'
55  
-    # Rakefile. If :sql, the schema is dumped as (potentially database-
56  
-    # specific) SQL statements. If :ruby, the schema is dumped as an
57  
-    # ActiveRecord::Schema file which can be loaded into any database that
58  
-    # supports migrations. Use :ruby if you want to have different database
59  
-    # adapters for, e.g., your development and test environments.
60  
-    mattr_accessor :schema_format, instance_accessor: false
61  
-    self.schema_format = :ruby
62  
-
63  
-    ##
64  
-    # :singleton-method:
65  
-    # Specify whether or not to use timestamps for migration versions
66  
-    mattr_accessor :timestamped_migrations, instance_accessor: false
67  
-    self.timestamped_migrations = true
68  
-
69  
-    mattr_accessor :connection_handler, instance_accessor: false
70  
-    self.connection_handler = ConnectionAdapters::ConnectionHandler.new
71  
-
72  
-    mattr_accessor :dependent_restrict_raises, instance_accessor: false
73  
-    self.dependent_restrict_raises = true
74 7
   end
75 8
 
76 9
   module Core
@@ -79,12 +12,71 @@ module Core
79 12
     included do
80 13
       ##
81 14
       # :singleton-method:
82  
-      # The connection handler
83  
-      config_attribute :connection_handler
  15
+      #
  16
+      # Accepts a logger conforming to the interface of Log4r which is then
  17
+      # passed on to any new database connections made and which can be
  18
+      # retrieved on both a class and instance level by calling +logger+.
  19
+      mattr_accessor :logger, instance_writer: false
84 20
 
85  
-      %w(logger configurations default_timezone schema_format timestamped_migrations).each do |name|
86  
-        config_attribute name, global: true
87  
-      end
  21
+      ##
  22
+      # :singleton-method:
  23
+      # Contains the database configuration - as is typically stored in config/database.yml -
  24
+      # as a Hash.
  25
+      #
  26
+      # For example, the following database.yml...
  27
+      #
  28
+      #   development:
  29
+      #     adapter: sqlite3
  30
+      #     database: db/development.sqlite3
  31
+      #
  32
+      #   production:
  33
+      #     adapter: sqlite3
  34
+      #     database: db/production.sqlite3
  35
+      #
  36
+      # ...would result in ActiveRecord::Base.configurations to look like this:
  37
+      #
  38
+      #   {
  39
+      #      'development' => {
  40
+      #         'adapter'  => 'sqlite3',
  41
+      #         'database' => 'db/development.sqlite3'
  42
+      #      },
  43
+      #      'production' => {
  44
+      #         'adapter'  => 'sqlite3',
  45
+      #         'database' => 'db/production.sqlite3'
  46
+      #      }
  47
+      #   }
  48
+      mattr_accessor :configurations, instance_writer: false
  49
+      self.configurations = {}
  50
+
  51
+      ##
  52
+      # :singleton-method:
  53
+      # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
  54
+      # dates and times from the database. This is set to :utc by default.
  55
+      mattr_accessor :default_timezone, instance_writer: false
  56
+      self.default_timezone = :utc
  57
+
  58
+      ##
  59
+      # :singleton-method:
  60
+      # Specifies the format to use when dumping the database schema with Rails'
  61
+      # Rakefile. If :sql, the schema is dumped as (potentially database-
  62
+      # specific) SQL statements. If :ruby, the schema is dumped as an
  63
+      # ActiveRecord::Schema file which can be loaded into any database that
  64
+      # supports migrations. Use :ruby if you want to have different database
  65
+      # adapters for, e.g., your development and test environments.
  66
+      mattr_accessor :schema_format, instance_writer: false
  67
+      self.schema_format = :ruby
  68
+
  69
+      ##
  70
+      # :singleton-method:
  71
+      # Specify whether or not to use timestamps for migration versions
  72
+      mattr_accessor :timestamped_migrations, instance_writer: false
  73
+      self.timestamped_migrations = true
  74
+
  75
+      class_attribute :connection_handler, instance_writer: false
  76
+      self.connection_handler = ConnectionAdapters::ConnectionHandler.new
  77
+
  78
+      mattr_accessor :dependent_restrict_raises, instance_writer: false
  79
+      self.dependent_restrict_raises = true
88 80
     end
89 81
 
90 82
     module ClassMethods
@@ -139,7 +131,13 @@ def arel_table
139 131
 
140 132
       # Returns the Arel engine.
141 133
       def arel_engine
142  
-        @arel_engine ||= connection_handler.retrieve_connection_pool(self) ? self : active_record_super.arel_engine
  134
+        @arel_engine ||= begin
  135
+          if Base == self || connection_handler.retrieve_connection_pool(self)
  136
+            self
  137
+          else
  138
+            superclass.arel_engine
  139
+          end
  140
+       end
143 141
       end
144 142
 
145 143
       private
8  activerecord/lib/active_record/explain.rb
... ...
@@ -1,12 +1,10 @@
1 1
 require 'active_support/lazy_load_hooks'
2 2
 
3 3
 module ActiveRecord
4  
-  ActiveSupport.on_load(:active_record_config) do
5  
-    mattr_accessor :auto_explain_threshold_in_seconds, instance_accessor: false
6  
-  end
7  
-
8 4
   module Explain
9  
-    delegate :auto_explain_threshold_in_seconds, :auto_explain_threshold_in_seconds=, to: 'ActiveRecord::Model'
  5
+    def self.extended(base)
  6
+      base.mattr_accessor :auto_explain_threshold_in_seconds, instance_accessor: false
  7
+    end
10 8
 
11 9
     # If auto explain is enabled, this method triggers EXPLAIN logging for the
12 10
     # queries triggered by the block if it takes more than the threshold as a
2  activerecord/lib/active_record/fixtures.rb
@@ -553,7 +553,7 @@ def table_rows
553 553
       rows[table_name] = fixtures.map do |label, fixture|
554 554
         row = fixture.to_hash
555 555
 
556  
-        if model_class && model_class < ActiveRecord::Model
  556
+        if model_class && model_class < ActiveRecord::Base
557 557
           # fill in timestamp columns if they aren't specified and the model is set to record_timestamps
558 558
           if model_class.record_timestamps
559 559
             timestamp_column_names.each do |c_name|
41  activerecord/lib/active_record/inheritance.rb
... ...
@@ -1,29 +1,22 @@
1  
-
2 1
 module ActiveRecord
3  
-  ActiveSupport.on_load(:active_record_config) do
4  
-    # Determine whether to store the full constant name including namespace when using STI
5  
-    mattr_accessor :store_full_sti_class, instance_accessor: false
6  
-    self.store_full_sti_class = true
7  
-  end
8  
-
9 2
   module Inheritance
10 3
     extend ActiveSupport::Concern
11 4
 
12 5
     included do
13  
-      config_attribute :store_full_sti_class
  6
+      # Determine whether to store the full constant name including namespace when using STI
  7
+      class_attribute :store_full_sti_class, instance_writer: false
  8
+      self.store_full_sti_class = true
14 9
     end
15 10
 
16 11
     module ClassMethods
17 12
       # True if this isn't a concrete subclass needing a STI type condition.
18 13
       def descends_from_active_record?
19  
-        sup = active_record_super
20  
-
21  
-        if sup.abstract_class?
22  
-          sup.descends_from_active_record?
23  
-        elsif self == Base
  14
+        if self == Base
24 15
           false
  16
+        elsif superclass.abstract_class?
  17
+          superclass.descends_from_active_record?
25 18
         else
26  
-          [Base, Model].include?(sup) || !columns_hash.include?(inheritance_column)
  19
+          superclass == Base || !columns_hash.include?(inheritance_column)
27 20
         end
28 21
       end
29 22
 
@@ -40,9 +33,8 @@ def symbolized_sti_name
40 33
         @symbolized_sti_name ||= sti_name.present? ? sti_name.to_sym : symbolized_base_class
41 34
       end
42 35
 
43  
-      # Returns the class descending directly from ActiveRecord::Base (or
44  
-      # that includes ActiveRecord::Model), or an  abstract class, if any, in
45  
-      # the inheritance hierarchy.
  36
+      # Returns the class descending directly from ActiveRecord::Base, or
  37
+      # an abstract class, if any, in the inheritance hierarchy.
46 38
       #
47 39
       # If A extends AR::Base, A.base_class will return A. If B descends from A
48 40
       # through some arbitrarily deep hierarchy, B.base_class will return A.
@@ -50,15 +42,14 @@ def symbolized_sti_name
50 42
       # If B < A and C < B and if A is an abstract_class then both B.base_class
51 43
       # and C.base_class would return B as the answer since A is an abstract_class.
52 44
       def base_class
53  
-        unless self < ActiveRecord::Tag
  45
+        unless self < Base
54 46
           raise ActiveRecordError, "#{name} doesn't belong in a hierarchy descending from ActiveRecord"
55 47
         end
56 48
 
57  
-        sup = active_record_super
58  
-        if sup == Base || sup == Model || sup.abstract_class?
  49
+        if superclass == Base || superclass.abstract_class?
59 50
           self
60 51
         else
61  
-          sup.base_class
  52
+          superclass.base_class
62 53
         end
63 54
       end
64 55
 
@@ -97,14 +88,6 @@ def instantiate(record, column_types = {})
97 88
         sti_class.allocate.init_with('attributes' => record, 'column_types' => column_types)
98 89
       end
99 90
 
100  
-      # For internal use.
101  
-      #
102  
-      # If this class includes ActiveRecord::Model then it won't have a
103  
-      # superclass. So this provides a way to get to the 'root' (ActiveRecord::Model).
104  
-      def active_record_super #:nodoc:
105  
-        superclass < Model ? superclass : Model
106  
-      end
107  
-
108 91
       protected
109 92
 
110 93
       # Returns the class type of the record using the current module as a prefix. So descendants of
8  activerecord/lib/active_record/locking/optimistic.rb
... ...
@@ -1,9 +1,4 @@
1 1
 module ActiveRecord
2  
-  ActiveSupport.on_load(:active_record_config) do
3  
-    mattr_accessor :lock_optimistically, instance_accessor: false
4  
-    self.lock_optimistically = true
5  
-  end
6  
-
7 2
   module Locking
8 3
     # == What is Optimistic Locking
9 4
     #
@@ -56,7 +51,8 @@ module Optimistic
56 51
       extend ActiveSupport::Concern
57 52
 
58 53
       included do
59  
-        config_attribute :lock_optimistically
  54
+        class_attribute :lock_optimistically, instance_writer: false
  55
+        self.lock_optimistically = true
60 56
       end
61 57
 
62 58
       def locking_enabled? #:nodoc:
167  activerecord/lib/active_record/model.rb
... ...
@@ -1,167 +0,0 @@
1  
-require 'active_support/core_ext/module/attribute_accessors'
2  
-
3  
-module ActiveRecord
4  
-  module Configuration # :nodoc:
5  
-    # This just abstracts out how we define configuration options in AR. Essentially we
6  
-    # have mattr_accessors on the ActiveRecord:Model constant that define global defaults.
7  
-    # Classes that then use AR get class_attributes defined, which means that when they
8  
-    # are assigned the default will be overridden for that class and subclasses. (Except
9  
-    # when options[:global] == true, in which case there is one global value always.)
10  
-    def config_attribute(name, options = {})
11  
-      if options[:global]
12  
-        class_eval <<-CODE, __FILE__, __LINE__ + 1
13  
-          def self.#{name};       ActiveRecord::Model.#{name};       end
14  
-          def #{name};            ActiveRecord::Model.#{name};       end
15  
-          def self.#{name}=(val); ActiveRecord::Model.#{name} = val; end
16  
-        CODE
17  
-      else
18  
-        options[:instance_writer] ||= false
19  
-        class_attribute name, options
20  
-
21  
-        singleton_class.class_eval <<-CODE, __FILE__, __LINE__ + 1
22  
-          remove_method :#{name}
23  
-          def #{name}; ActiveRecord::Model.#{name}; end
24  
-        CODE
25  
-      end
26  
-    end
27  
-  end
28  
-
29  
-  # This allows us to detect an ActiveRecord::Model while it's in the process of
30  
-  # being included.
31  
-  module Tag; end
32  
-
33  
-  # <tt>ActiveRecord::Model</tt> can be included into a class to add Active Record
34  
-  # persistence. This is an alternative to inheriting from <tt>ActiveRecord::Base</tt>.
35  
-  #
36  
-  #     class Post
37  
-  #       include ActiveRecord::Model
38  
-  #     end
39  
-  module Model
40  
-    extend ActiveSupport::Concern
41  
-    extend ConnectionHandling
42  
-    extend ActiveModel::Observing::ClassMethods
43  
-
44  
-    def self.append_features(base)
45  
-      base.class_eval do
46  
-        include Tag
47  
-        extend Configuration
48  
-      end
49  
-
50  
-      super
51  
-    end
52  
-
53  
-    included do
54  
-      extend ActiveModel::Naming
55  
-      extend ActiveSupport::Benchmarkable
56  
-      extend ActiveSupport::DescendantsTracker
57  
-
58  
-      extend QueryCache::ClassMethods
59  
-      extend Querying
60  
-      extend Translation
61  
-      extend DynamicMatchers
62  
-      extend Explain
63  
-      extend ConnectionHandling
64  
-
65  
-      initialize_generated_modules unless self == Base
66  
-    end
67  
-
68  
-    include Persistence
69  
-    include ReadonlyAttributes
70  
-    include ModelSchema
71  
-    include Inheritance
72  
-    include Scoping
73  
-    include Sanitization
74  
-    include AttributeAssignment
75  
-    include ActiveModel::Conversion
76  
-    include Integration
77  
-    include Validations
78  
-    include CounterCache
79  
-    include Locking::Optimistic
80  
-    include Locking::Pessimistic
81  
-    include AttributeMethods
82  
-    include Callbacks
83  
-    include ActiveModel::Observing
84  
-    include Timestamp
85  
-    include Associations
86  
-    include ActiveModel::SecurePassword
87  
-    include AutosaveAssociation
88  
-    include NestedAttributes
89  
-    include Aggregations
90  
-    include Transactions
91  
-    include Reflection
92  
-    include Serialization
93  
-    include Store
94  
-    include Core
95  
-
96  
-    class << self
97  
-      def arel_engine
98  
-        self
99  
-      end
100  
-
101  
-      def abstract_class?
102  
-        false
103  
-      end
104  
-
105  
-      # Defines the name of the table column which will store the class name on single-table
106  
-      # inheritance situations.
107  
-      #
108  
-      # The default inheritance column name is +type+, which means it's a
109  
-      # reserved word inside Active Record. To be able to use single-table
110  
-      # inheritance with another column name, or to use the column +type+ in
111  
-      # your own model for something else, you can set +inheritance_column+:
112  
-      #
113  
-      #     self.inheritance_column = 'zoink'
114  
-      def inheritance_column
115  
-        'type'
116  
-      end
117  
-    end
118  
-
119  
-    class DeprecationProxy < BasicObject #:nodoc:
120  
-      def initialize(model = Model, base = Base)
121  
-        @model = model
122  
-        @base  = base
123  
-      end
124  
-
125  
-      def method_missing(name, *args, &block)
126  
-        if @model.respond_to?(name, true)
127  
-          @model.send(name, *args, &block)
128  
-        else
129  
-          ::ActiveSupport::Deprecation.warn(
130  
-            "The object passed to the active_record load hook was previously ActiveRecord::Base " \
131  
-            "(a Class). Now it is ActiveRecord::Model (a Module). You have called `#{name}' which " \
132  
-            "is only defined on ActiveRecord::Base. Please change your code so that it works with " \
133  
-            "a module rather than a class. (Model is included in Base, so anything added to Model " \
134  
-            "will be available on Base as well.)"
135  
-          )
136  
-          @base.send(name, *args, &block)
137  
-        end
138  
-      end
139  
-
140  
-      alias send method_missing
141  
-
142  
-      def extend(*mods)
143  
-        ::ActiveSupport::Deprecation.warn(
144  
-          "The object passed to the active_record load hook was previously ActiveRecord::Base " \
145  
-          "(a Class). Now it is ActiveRecord::Model (a Module). You have called `extend' which " \
146  
-          "would add singleton methods to Model. This is presumably not what you want, since the " \
147  
-          "methods would not be inherited down to Base. Rather than using extend, please use " \
148  
-          "ActiveSupport::Concern + include, which will ensure that your class methods are " \
149  
-          "inherited."
150  
-        )
151  
-        @base.extend(*mods)
152  
-      end
153  
-    end
154  
-  end
155  
-
156  
-  # This hook is where config accessors on Model get defined.
157  
-  #
158  
-  # We don't want to just open the Model module and add stuff to it in other files, because
159  
-  # that would cause Model to load, which causes all sorts of loading order issues.
160  
-  #
161  
-  # We need this hook rather than just using the :active_record one, because users of the
162  
-  # :active_record hook may need to use config options.
163  
-  ActiveSupport.run_load_hooks(:active_record_config, Model)
164  
-
165  
-  # Load Base at this point, because the active_record load hook is run in that file.
166  
-  Base
167  
-end
47  activerecord/lib/active_record/model_schema.rb
... ...
@@ -1,18 +1,4 @@
1  
-
2 1
 module ActiveRecord
3  
-  ActiveSupport.on_load(:active_record_config) do
4  
-    mattr_accessor :primary_key_prefix_type, instance_accessor: false
5  
-
6  
-    mattr_accessor :table_name_prefix, instance_accessor: false
7  
-    self.table_name_prefix = ""
8  
-
9  
-    mattr_accessor :table_name_suffix, instance_accessor: false
10  
-    self.table_name_suffix = ""
11  
-
12  
-    mattr_accessor :pluralize_table_names, instance_accessor: false
13  
-    self.pluralize_table_names = true
14  
-  end
15  
-
16 2
   module ModelSchema
17 3
     extend ActiveSupport::Concern
18 4
 
@@ -24,7 +10,7 @@ module ModelSchema
24 10
       # the Product class will look for "productid" instead of "id" as the primary column. If the
25 11
       # latter is specified, the Product class will look for "product_id" instead of "id". Remember
26 12
       # that this is a global setting for all Active Records.
27  
-      config_attribute :primary_key_prefix_type, global: true
  13
+      mattr_accessor :primary_key_prefix_type, instance_writer: false
28 14
 
29 15
       ##
30 16
       # :singleton-method:
@@ -36,20 +22,25 @@ module ModelSchema
36 22
       # If you are organising your models within modules you can add a prefix to the models within
37 23
       # a namespace by defining a singleton method in the parent module called table_name_prefix which
38 24
       # returns your chosen prefix.
39  
-      config_attribute :table_name_prefix
  25
+      class_attribute :table_name_prefix, instance_writer: false
  26
+      self.table_name_prefix = ""
40 27
 
41 28
       ##
42 29
       # :singleton-method:
43 30
       # Works like +table_name_prefix+, but appends instead of prepends (set to "_basecamp" gives "projects_basecamp",
44 31
       # "people_basecamp"). By default, the suffix is the empty string.
45  
-      config_attribute :table_name_suffix
  32
+      class_attribute :table_name_suffix, instance_writer: false
  33
+      self.table_name_suffix = ""
46 34
 
47 35
       ##
48 36
       # :singleton-method:
49 37
       # Indicates whether table names should be the pluralized versions of the corresponding class names.
50 38
       # If true, the default table name for a Product class will be +products+. If false, it would just be +product+.
51 39
       # See table_name for the full rules on table/class naming. This is true, by default.
52  
-      config_attribute :pluralize_table_names
  40
+      class_attribute :pluralize_table_names, instance_writer: false
  41
+      self.pluralize_table_names = true
  42
+
  43
+      self.inheritance_column = 'type'
53 44
     end
54 45
 
55 46
     module ClassMethods
@@ -144,9 +135,9 @@ def quoted_table_name
144 135
       # Computes the table name, (re)sets it internally, and returns it.
145 136
       def reset_table_name #:nodoc:
146 137
         self.table_name = if abstract_class?
147  
-          active_record_super == Base ? nil : active_record_super.table_name
148  
-        elsif active_record_super.abstract_class?
149  
-          active_record_super.table_name || compute_table_name
  138
+          superclass == Base ? nil : superclass.table_name
  139
+        elsif superclass.abstract_class?
  140
+          superclass.table_name || compute_table_name
150 141
         else
151 142
           compute_table_name
152 143
         end
@@ -156,9 +147,17 @@ def full_table_name_prefix #:nodoc:
156 147
         (parents.detect{ |p| p.respond_to?(:table_name_prefix) } || self).table_name_prefix
157 148
       end
158 149
 
159  
-      # The name of the column containing the object's class when Single Table Inheritance is used
  150
+      # Defines the name of the table column which will store the class name on single-table
  151
+      # inheritance situations.
  152
+      #
  153
+      # The default inheritance column name is +type+, which means it's a
  154
+      # reserved word inside Active Record. To be able to use single-table
  155
+      # inheritance with another column name, or to use the column +type+ in
  156
+      # your own model for something else, you can set +inheritance_column+:
  157
+      #
  158
+      #     self.inheritance_column = 'zoink'
160 159
       def inheritance_column
161  
-        (@inheritance_column ||= nil) || active_record_super.inheritance_column
  160
+        (@inheritance_column ||= nil) || superclass.inheritance_column
162 161
       end
163 162
 
164 163
       # Sets the value of inheritance_column
@@ -331,7 +330,7 @@ def compute_table_name
331 330
         base = base_class
332 331
         if self == base
333 332
           # Nested classes are prefixed with singular parent table name.
334  
-          if parent < ActiveRecord::Model && !parent.abstract_class?
  333
+          if parent < Base && !parent.abstract_class?
335 334
             contained = parent.table_name
336 335
             contained = contained.singularize if parent.pluralize_table_names
337 336
             contained += '_'
8  activerecord/lib/active_record/nested_attributes.rb
@@ -3,11 +3,6 @@
3 3
 require 'active_support/core_ext/hash/indifferent_access'
4 4
 
5 5
 module ActiveRecord
6  
-  ActiveSupport.on_load(:active_record_config) do
7  
-    mattr_accessor :nested_attributes_options, instance_accessor: false
8  
-    self.nested_attributes_options = {}
9  
-  end
10  
-
11 6
   module NestedAttributes #:nodoc:
12 7
     class TooManyRecords < ActiveRecordError
13 8
     end
@@ -15,7 +10,8 @@ class TooManyRecords < ActiveRecordError
15 10
     extend ActiveSupport::Concern
16 11
 
17 12
     included do
18  
-      config_attribute :nested_attributes_options
  13
+      class_attribute :nested_attributes_options, instance_writer: false
  14
+      self.nested_attributes_options = {}
19 15
     end
20 16
 
21 17
     # = Active Record Nested Attributes
11  activerecord/lib/active_record/railtie.rb
@@ -80,7 +80,7 @@ class Railtie < Rails::Railtie # :nodoc:
80 80
             if File.file?(filename)
81 81
               cache = Marshal.load File.binread filename
82 82
               if cache.version == ActiveRecord::Migrator.current_version
83  
-                ActiveRecord::Model.connection.schema_cache = cache
  83
+                self.connection.schema_cache = cache
84 84
               else
85 85
                 warn "Ignoring db/schema_cache.dump because it has expired. The current schema version is #{ActiveRecord::Migrator.current_version}, but the one in the cache is #{cache.version}."
86 86
               end
@@ -122,8 +122,8 @@ class Railtie < Rails::Railtie # :nodoc:
122 122
 
123 123
       ActiveSupport.on_load(:active_record) do
124 124
         ActionDispatch::Reloader.send(hook) do
125  
-          ActiveRecord::Model.clear_reloadable_connections!
126  
-          ActiveRecord::Model.clear_cache!
  125
+          ActiveRecord::Base.clear_reloadable_connections!
  126
+          ActiveRecord::Base.clear_cache!
127 127
         end
128 128
       end
129 129
     end
@@ -135,13 +135,12 @@ class Railtie < Rails::Railtie # :nodoc:
135 135
 
136 136
     config.after_initialize do |app|
137 137
       ActiveSupport.on_load(:active_record) do
138  
-        ActiveRecord::Model.instantiate_observers
  138
+        instantiate_observers
139 139
 
140 140
         ActionDispatch::Reloader.to_prepare do
141  
-          ActiveRecord::Model.instantiate_observers
  141
+          ActiveRecord::Base.instantiate_observers
142 142
         end
143 143
       end
144  
-
145 144
     end
146 145
   end
147 146
 end
2  activerecord/lib/active_record/relation/finder_methods.rb
@@ -159,7 +159,7 @@ def last!
159 159
     #   Person.exists?(false)
160 160
     #   Person.exists?
161 161
     def exists?(conditions = :none)
162  
-      conditions = conditions.id if ActiveRecord::Model === conditions
  162
+      conditions = conditions.id if Base === conditions
163 163
       return false if !conditions
164 164
 
165 165
       join_dependency = construct_join_dependency_for_association_find
6  activerecord/lib/active_record/relation/predicate_builder.rb
@@ -40,7 +40,7 @@ def self.expand(klass, table, column, value)
40 40
       #
41 41
       # For polymorphic relationships, find the foreign key and type:
42 42
       # PriceEstimate.where(:estimate_of => treasure)
43  
-      if klass && value.class < ActiveRecord::Tag && reflection = klass.reflect_on_association(column.to_sym)
  43
+      if klass && value.class < Base && reflection = klass.reflect_on_association(column.to_sym)
44 44
         if reflection.polymorphic?
45 45
           queries << build(table[reflection.foreign_type], value.class.base_class)
46 46
         end
@@ -67,7 +67,7 @@ def self.references(attributes)
67 67
       def self.build(attribute, value)
68 68
         case value
69 69
         when Array, ActiveRecord::Associations::CollectionProxy
70  
-          values = value.to_a.map {|x| x.is_a?(ActiveRecord::Model) ? x.id : x}
  70
+          values = value.to_a.map {|x| x.is_a?(Base) ? x.id : x}
71 71
           ranges, values = values.partition {|v| v.is_a?(Range)}
72 72
 
73 73
           values_predicate = if values.include?(nil)
@@ -93,7 +93,7 @@ def self.build(attribute, value)
93 93
           attribute.in(value.arel.ast)
94 94
         when Range
95 95
           attribute.in(value)
96  
-        when ActiveRecord::Model
  96
+        when ActiveRecord::Base
97 97
           attribute.eq(value.id)
98 98
         when Class
99 99
           # FIXME: I think we need to deprecate this behavior
2  activerecord/lib/active_record/result.rb
@@ -56,7 +56,7 @@ def hash_rows
56 56
       @hash_rows ||=
57 57
         begin
58 58
           # We freeze the strings to prevent them getting duped when
59  
-          # used as keys in ActiveRecord::Model's @attributes hash
  59
+          # used as keys in ActiveRecord::Base's @attributes hash
60 60
           columns = @columns.map { |c| c.dup.freeze }
61 61
           @rows.map { |row|
62 62
             Hash[columns.zip(row)]
11  activerecord/lib/active_record/serialization.rb
... ...
@@ -1,19 +1,12 @@
1 1
 module ActiveRecord #:nodoc:
2  
-  ActiveSupport.on_load(:active_record_config) do
3  
-    mattr_accessor :include_root_in_json, instance_accessor: false
4  
-    self.include_root_in_json = true
5  
-  end
6  
-
7 2
   # = Active Record Serialization
8 3
   module Serialization
9 4
     extend ActiveSupport::Concern
10 5
     include ActiveModel::Serializers::JSON
11 6
 
12 7
     included do
13  
-      singleton_class.class_eval do
14  
-        remove_method :include_root_in_json
15  
-        delegate :include_root_in_json, to: 'ActiveRecord::Model'
16  
-      end
  8
+      mattr_accessor :include_root_in_json, instance_accessor: false
  9
+      self.include_root_in_json = true
17 10
     end
18 11
 
19 12
     def serializable_hash(options = nil)
5  activerecord/lib/active_record/timestamp.rb
... ...
@@ -1,8 +1,6 @@
1 1
 
2 2
 module ActiveRecord
3 3
   ActiveSupport.on_load(:active_record_config) do
4  
-    mattr_accessor :record_timestamps, instance_accessor: false
5  
-    self.record_timestamps = true
6 4
   end
7 5
 
8 6
   # = Active Record Timestamp
@@ -37,7 +35,8 @@ module Timestamp
37 35
     extend ActiveSupport::Concern
38 36
 
39 37
     included do
40  
-      config_attribute :record_timestamps, instance_writer: true
  38
+      class_attribute :record_timestamps
  39
+      self.record_timestamps = true
41 40
     end
42 41
 
43 42
     def initialize_dup(other) # :nodoc:
6  activerecord/test/cases/adapter_test.rb
@@ -69,16 +69,16 @@ def test_show_nonexistent_variable_returns_nil
69 69
       def test_not_specifying_database_name_for_cross_database_selects
70 70
         begin
71 71
           assert_nothing_raised do
72  
-            ActiveRecord::Model.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database))
  72
+            ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['arunit'].except(:database))
73 73
 
74 74
             config = ARTest.connection_config
75  
-            ActiveRecord::Model.connection.execute(
  75
+            ActiveRecord::Base.connection.execute(
76 76
               "SELECT #{config['arunit']['database']}.pirates.*, #{config['arunit2']['database']}.courses.* " \
77 77
               "FROM #{config['arunit']['database']}.pirates, #{config['arunit2']['database']}.courses"
78 78
             )
79 79
           end
80 80
         ensure
81  
-          ActiveRecord::Model.establish_connection 'arunit'
  81
+          ActiveRecord::Base.establish_connection 'arunit'
82 82
         end
83 83
       end
84 84
     end
22  activerecord/test/cases/adapters/mysql/connection_test.rb
@@ -3,13 +3,13 @@
3 3
 class MysqlConnectionTest < ActiveRecord::TestCase
4 4
   def setup
5 5
     super
6  
-    @connection = ActiveRecord::Model.connection
  6
+    @connection = ActiveRecord::Base.connection
7 7
   end
8 8
 
9 9
   def test_mysql_reconnect_attribute_after_connection_with_reconnect_true
10 10
     run_without_connection do |orig_connection|
11  
-      ActiveRecord::Model.establish_connection(orig_connection.merge({:reconnect => true}))
12  
-      assert ActiveRecord::Model.connection.raw_connection.reconnect
  11
+      ActiveRecord::Base.establish_connection(orig_connection.merge({:reconnect => true}))
  12
+      assert ActiveRecord::Base.connection.raw_connection.reconnect
13 13
     end
14 14
   end
15 15
 
@@ -25,8 +25,8 @@ def test_connect_with_url
25 25
 
26 26
   def test_mysql_reconnect_attribute_after_connection_with_reconnect_false
27 27
     run_without_connection do |orig_connection|
28  
-      ActiveRecord::Model.establish_connection(orig_connection.merge({:reconnect => false}))
29  
-      assert !ActiveRecord::Model.connection.raw_connection.reconnect
  28
+      ActiveRecord::Base.establish_connection(orig_connection.merge({:reconnect => false}))
  29
+      assert !ActiveRecord::Base.connection.raw_connection.reconnect
30 30
     end
31 31
   end
32 32
 
@@ -117,7 +117,7 @@ def test_exec_typecasts_bind_vals
117 117
   # Test that MySQL allows multiple results for stored procedures
118 118
   if defined?(Mysql) && Mysql.const_defined?(:CLIENT_MULTI_RESULTS)
119 119
     def test_multi_results
120  
-      rows = ActiveRecord::Model.connection.select_rows('CALL ten();')
  120
+      rows = ActiveRecord::Base.connection.select_rows('CALL ten();')
121 121
       assert_equal 10, rows[0][0].to_i, "ten() did not return 10 as expected: #{rows.inspect}"
122 122
       assert @connection.active?, "Bad connection use by 'MysqlAdapter.select_rows'"
123 123
     end
@@ -130,9 +130,9 @@ def test_mysql_default_in_strict_mode
130 130
 
131 131
   def test_mysql_strict_mode_disabled_dont_override_global_sql_mode
132 132
     run_without_connection do |orig_connection|
133  
-      ActiveRecord::Model.establish_connection(orig_connection.merge({:strict => false}))
134  
-      global_sql_mode = ActiveRecord::Model.connection.exec_query "SELECT @@GLOBAL.sql_mode"
135  
-      session_sql_mode = ActiveRecord::Model.connection.exec_query "SELECT @@SESSION.sql_mode"
  133
+      ActiveRecord::Base.establish_connection(orig_connection.merge({:strict => false}))
  134
+      global_sql_mode = ActiveRecord::Base.connection.exec_query "SELECT @@GLOBAL.sql_mode"
  135
+      session_sql_mode = ActiveRecord::Base.connection.exec_query "SELECT @@SESSION.sql_mode"
136 136
       assert_equal global_sql_mode.rows, session_sql_mode.rows
137 137
     end
138 138
   end
@@ -140,11 +140,11 @@ def test_mysql_strict_mode_disabled_dont_override_global_sql_mode
140 140
   private
141 141
 
142 142
   def run_without_connection
143  
-    original_connection = ActiveRecord::Model.remove_connection
  143
+    original_connection = ActiveRecord::Base.remove_connection
144 144
     begin
145 145
       yield original_connection
146 146
     ensure
147  
-      ActiveRecord::Model.establish_connection(original_connection)
  147
+      ActiveRecord::Base.establish_connection(original_connection)
148 148
     end
149 149
   end
150 150
 end
12  activerecord/test/cases/adapters/mysql2/connection_test.rb
@@ -3,7 +3,7 @@
3 3
 class MysqlConnectionTest < ActiveRecord::TestCase
4 4
   def setup
5 5
     super
6  
-    @connection = ActiveRecord::Model.connection
  6
+    @connection = ActiveRecord::Base.connection
7 7
     @connection.extend(LogIntercepter)
8 8
     @connection.intercepted = true
9 9
   end
@@ -46,9 +46,9 @@ def test_mysql_default_in_strict_mode
46 46