1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
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:
#
# class Post
# include ActiveRecord::Model
# end
#
module Model
extend ActiveSupport::Concern
extend ConnectionHandling
extend ActiveModel::Observing::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
include Tag
extend Configuration
end
super
end
included do
extend ActiveModel::Naming
extend ActiveSupport::Benchmarkable
extend ActiveSupport::DescendantsTracker
extend QueryCache::ClassMethods
extend Querying
extend Translation
extend DynamicMatchers
extend Explain
extend ConnectionHandling
initialize_generated_modules unless self == Base
end
include Persistence
include ReadonlyAttributes
include ModelSchema
include Inheritance
include Scoping
include Sanitization
include AttributeAssignment
include ActiveModel::Conversion
include Integration
include Validations
include CounterCache
include Locking::Optimistic
include Locking::Pessimistic
include AttributeMethods
include Callbacks
include ActiveModel::Observing
include Timestamp
include Associations
include ActiveModel::SecurePassword
include AutosaveAssociation
include NestedAttributes
include Aggregations
include Transactions
include Reflection
include Serialization
include Store
include Core
class << self
def arel_engine
self
end
def abstract_class?
false
end
# Defines the name of the table column which will store the class name on single-table
# inheritance situations.
#
# The default inheritance column name is +type+, which means it's a
# reserved word inside Active Record. To be able to use single-table
# inheritance with another column name, or to use the column +type+ in
# your own model for something else, you can override this method to
# return a different name:
#
# def self.inheritance_column
# 'zoink'
# end
def inheritance_column
'type'
end
end
class DeprecationProxy < BasicObject #:nodoc:
def initialize(model = Model, base = Base)
@model = model
@base = base
end
def method_missing(name, *args, &block)
if @model.respond_to?(name, true)
@model.send(name, *args, &block)
else
::ActiveSupport::Deprecation.warn(
"The object passed to the active_record load hook was previously ActiveRecord::Base " \
"(a Class). Now it is ActiveRecord::Model (a Module). You have called `#{name}' which " \
"is only defined on ActiveRecord::Base. Please change your code so that it works with " \
"a module rather than a class. (Model is included in Base, so anything added to Model " \
"will be available on Base as well.)"
)
@base.send(name, *args, &block)
end
end
alias send method_missing
def extend(*mods)
::ActiveSupport::Deprecation.warn(
"The object passed to the active_record load hook was previously ActiveRecord::Base " \
"(a Class). Now it is ActiveRecord::Model (a Module). You have called `extend' which " \
"would add singleton methods to Model. This is presumably not what you want, since the " \
"methods would not be inherited down to Base. Rather than using extend, please use " \
"ActiveSupport::Concern + include, which will ensure that your class methods are " \
"inherited."
)
@base.extend(*mods)
end
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
|