active_mocker 1.8.4 → 2.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +4 -2
- data/lib/active_mocker.rb +9 -25
- data/lib/active_mocker/config.rb +26 -46
- data/lib/active_mocker/generate.rb +115 -110
- data/lib/active_mocker/loaded_mocks.rb +76 -65
- data/lib/active_mocker/mock/base.rb +283 -287
- data/lib/active_mocker/mock/has_many.rb +2 -0
- data/lib/active_mocker/mock_creator.rb +262 -0
- data/lib/active_mocker/mock_template.erb +9 -186
- data/lib/active_mocker/mock_template/_associations.erb +82 -0
- data/lib/active_mocker/mock_template/_attributes.erb +11 -0
- data/lib/active_mocker/mock_template/_class_methods.erb +41 -0
- data/lib/active_mocker/mock_template/_defined_methods.erb +10 -0
- data/lib/active_mocker/mock_template/_modules_constants.erb +10 -0
- data/lib/active_mocker/mock_template/_scopes.erb +23 -0
- data/lib/active_mocker/null_progress.rb +9 -0
- data/lib/active_mocker/output_capture.rb +32 -0
- data/lib/active_mocker/parent_class.rb +64 -0
- data/lib/active_mocker/progress.rb +13 -0
- data/lib/active_mocker/public_methods.rb +15 -23
- data/lib/active_mocker/rspec.rb +16 -0
- data/lib/active_mocker/rspec_helper.rb +10 -8
- data/lib/active_mocker/task.rake +6 -1
- data/lib/active_mocker/template_creator.rb +22 -0
- data/lib/active_mocker/version.rb +1 -1
- metadata +43 -103
- data/lib/active_mocker/active_record.rb +0 -74
- data/lib/active_mocker/active_record/field.rb +0 -39
- data/lib/active_mocker/active_record/relationships.rb +0 -110
- data/lib/active_mocker/active_record/schema.rb +0 -81
- data/lib/active_mocker/active_record/scope.rb +0 -22
- data/lib/active_mocker/active_record/table.rb +0 -26
- data/lib/active_mocker/active_record/unknown_class_method.rb +0 -17
- data/lib/active_mocker/active_record/unknown_module.rb +0 -30
- data/lib/active_mocker/db_to_ruby_type.rb +0 -29
- data/lib/active_mocker/file_reader.rb +0 -11
- data/lib/active_mocker/model_reader.rb +0 -191
- data/lib/active_mocker/model_schema.rb +0 -285
- data/lib/active_mocker/model_schema/assemble.rb +0 -220
- data/lib/active_mocker/reparameterize.rb +0 -41
- data/lib/active_mocker/ruby_parse.rb +0 -68
- data/lib/active_mocker/schema_reader.rb +0 -30
- data/lib/active_mocker/string_reader.rb +0 -18
@@ -1,329 +1,325 @@
|
|
1
1
|
module ActiveMocker
|
2
|
-
module Mock
|
3
|
-
class Base
|
2
|
+
module Mock
|
3
|
+
class Base
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
include DoNothingActiveRecordMethods
|
6
|
+
include MockAbilities
|
7
|
+
include TemplateMethods
|
8
|
+
extend Queries
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
ActiveMocker::LoadedMocks.send(:add_subclass, subclass)
|
13
|
-
end
|
14
|
-
|
15
|
-
class << self
|
16
|
-
|
17
|
-
# Creates an object (or multiple objects) and saves it to memory.
|
18
|
-
#
|
19
|
-
# The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the
|
20
|
-
# attributes on the objects that are to be created.
|
21
|
-
#
|
22
|
-
# ==== Examples
|
23
|
-
# # Create a single new object
|
24
|
-
# User.create(first_name: 'Jamie')
|
25
|
-
#
|
26
|
-
# # Create an Array of new objects
|
27
|
-
# User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
|
28
|
-
#
|
29
|
-
# # Create a single object and pass it into a block to set other attributes.
|
30
|
-
# User.create(first_name: 'Jamie') do |u|
|
31
|
-
# u.is_admin = false
|
32
|
-
# end
|
33
|
-
#
|
34
|
-
# # Creating an Array of new objects using a block, where the block is executed for each object:
|
35
|
-
# User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
|
36
|
-
# u.is_admin = false
|
37
|
-
# end
|
38
|
-
def create(attributes = {}, &block)
|
39
|
-
if attributes.is_a?(Array)
|
40
|
-
attributes.collect { |attr| create(attr, &block) }
|
41
|
-
else
|
42
|
-
record = new(id: attributes[:id] || attributes['id'])
|
43
|
-
record.save
|
44
|
-
record.assign_attributes(attributes, &block)
|
45
|
-
record._create_caller_locations = caller_locations
|
46
|
-
record
|
10
|
+
def self.inherited(subclass)
|
11
|
+
return ActiveMocker::LoadedMocks.send(:add, subclass) if subclass.superclass == Base
|
47
12
|
end
|
48
|
-
end
|
49
13
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
14
|
+
class << self
|
15
|
+
|
16
|
+
# Creates an object (or multiple objects) and saves it to memory.
|
17
|
+
#
|
18
|
+
# The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the
|
19
|
+
# attributes on the objects that are to be created.
|
20
|
+
#
|
21
|
+
# ==== Examples
|
22
|
+
# # Create a single new object
|
23
|
+
# User.create(first_name: 'Jamie')
|
24
|
+
#
|
25
|
+
# # Create an Array of new objects
|
26
|
+
# User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }])
|
27
|
+
#
|
28
|
+
# # Create a single object and pass it into a block to set other attributes.
|
29
|
+
# User.create(first_name: 'Jamie') do |u|
|
30
|
+
# u.is_admin = false
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# # Creating an Array of new objects using a block, where the block is executed for each object:
|
34
|
+
# User.create([{ first_name: 'Jamie' }, { first_name: 'Jeremy' }]) do |u|
|
35
|
+
# u.is_admin = false
|
36
|
+
# end
|
37
|
+
def create(attributes = {}, &block)
|
38
|
+
if attributes.is_a?(Array)
|
39
|
+
attributes.collect { |attr| create(attr, &block) }
|
40
|
+
else
|
41
|
+
record = new(id: attributes[:id] || attributes['id'])
|
42
|
+
record.save
|
43
|
+
record.assign_attributes(attributes, &block)
|
44
|
+
record._create_caller_locations = caller_locations
|
45
|
+
record
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
alias_method :create!, :create
|
50
|
+
|
51
|
+
def records
|
52
|
+
@records ||= Records.new
|
53
|
+
end
|
54
|
+
|
55
|
+
private :records
|
56
|
+
|
57
|
+
delegate :insert, :exists?, :to_a, :to => :records
|
58
|
+
delegate :first, :last, :to => :all
|
59
|
+
|
60
|
+
# Delete an object (or multiple objects) that has the given id.
|
61
|
+
#
|
62
|
+
# This essentially finds the object (or multiple objects) with the given id and then calls delete on it.
|
63
|
+
#
|
64
|
+
# ==== Parameters
|
65
|
+
#
|
66
|
+
# * +id+ - Can be either an Integer or an Array of Integers.
|
67
|
+
#
|
68
|
+
# ==== Examples
|
69
|
+
#
|
70
|
+
# # Destroy a single object
|
71
|
+
# TodoMock.delete(1)
|
72
|
+
#
|
73
|
+
# # Destroy multiple objects
|
74
|
+
# todos = [1,2,3]
|
75
|
+
# TodoMock.delete(todos)
|
76
|
+
def delete(id)
|
77
|
+
if id.is_a?(Array)
|
78
|
+
id.map { |one_id| delete(one_id) }
|
79
|
+
else
|
80
|
+
find(id).delete
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
alias_method :destroy, :delete
|
85
|
+
|
86
|
+
# Deletes the records matching +conditions+.
|
87
|
+
#
|
88
|
+
# Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
|
89
|
+
def delete_all(conditions=nil)
|
90
|
+
return records.reset if conditions.nil?
|
91
|
+
super
|
92
|
+
end
|
93
|
+
|
94
|
+
alias_method :destroy_all, :delete_all
|
95
|
+
|
96
|
+
# @api private
|
97
|
+
def from_limit?
|
98
|
+
false
|
99
|
+
end
|
100
|
+
|
101
|
+
def abstract_class?
|
102
|
+
true
|
103
|
+
end
|
104
|
+
|
105
|
+
def build_type(type)
|
106
|
+
@@built_types ||= {}
|
107
|
+
@@built_types[type] ||= Virtus::Attribute.build(type)
|
108
|
+
end
|
109
|
+
|
110
|
+
def classes(klass)
|
111
|
+
ActiveMocker::LoadedMocks.find(klass)
|
112
|
+
end
|
113
|
+
|
114
|
+
def new_relation(collection)
|
115
|
+
ScopeRelation.new(collection)
|
116
|
+
end
|
117
|
+
|
118
|
+
private :classes, :build_type, :new_relation
|
119
|
+
|
120
|
+
public
|
121
|
+
|
122
|
+
def clear_mock
|
123
|
+
clear_mocked_methods
|
124
|
+
delete_all
|
125
|
+
end
|
126
|
+
|
127
|
+
def _find_associations_by_class(klass_name)
|
128
|
+
associations_by_class[klass_name.to_s]
|
129
|
+
end
|
130
|
+
|
131
|
+
def created_with(version)
|
132
|
+
raise UpdateMocksError.new(self.name, version, ActiveMocker::VERSION) if version != ActiveMocker::VERSION
|
133
|
+
end
|
134
|
+
|
135
|
+
private :created_with
|
55
136
|
|
56
|
-
private :records
|
57
|
-
|
58
|
-
delegate :insert, :exists?, :to_a, :to => :records
|
59
|
-
delegate :first, :last, :to => :all
|
60
|
-
|
61
|
-
# Delete an object (or multiple objects) that has the given id.
|
62
|
-
#
|
63
|
-
# This essentially finds the object (or multiple objects) with the given id and then calls delete on it.
|
64
|
-
#
|
65
|
-
# ==== Parameters
|
66
|
-
#
|
67
|
-
# * +id+ - Can be either an Integer or an Array of Integers.
|
68
|
-
#
|
69
|
-
# ==== Examples
|
70
|
-
#
|
71
|
-
# # Destroy a single object
|
72
|
-
# TodoMock.delete(1)
|
73
|
-
#
|
74
|
-
# # Destroy multiple objects
|
75
|
-
# todos = [1,2,3]
|
76
|
-
# TodoMock.delete(todos)
|
77
|
-
def delete(id)
|
78
|
-
if id.is_a?(Array)
|
79
|
-
id.map { |one_id| delete(one_id) }
|
80
|
-
else
|
81
|
-
find(id).delete
|
82
137
|
end
|
83
|
-
end
|
84
|
-
|
85
|
-
alias_method :destroy, :delete
|
86
|
-
|
87
|
-
# Deletes the records matching +conditions+.
|
88
|
-
#
|
89
|
-
# Post.where(person_id: 5).where(category: ['Something', 'Else']).delete_all
|
90
|
-
def delete_all(conditions=nil)
|
91
|
-
return records.reset if conditions.nil?
|
92
|
-
super
|
93
|
-
end
|
94
|
-
|
95
|
-
alias_method :destroy_all, :delete_all
|
96
|
-
|
97
|
-
# @api private
|
98
|
-
def from_limit?
|
99
|
-
false
|
100
|
-
end
|
101
|
-
|
102
|
-
def abstract_class?
|
103
|
-
true
|
104
|
-
end
|
105
|
-
|
106
|
-
def build_type(type)
|
107
|
-
@@built_types ||= {}
|
108
|
-
@@built_types[type] ||= Virtus::Attribute.build(type)
|
109
|
-
end
|
110
|
-
|
111
|
-
def classes(klass)
|
112
|
-
ActiveMocker::LoadedMocks.find(klass)
|
113
|
-
end
|
114
|
-
|
115
|
-
def new_relation(collection)
|
116
|
-
ScopeRelation.new(collection)
|
117
|
-
end
|
118
138
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
def clear_mock
|
124
|
-
clear_mocked_methods
|
125
|
-
delete_all
|
126
|
-
end
|
127
|
-
|
128
|
-
def _find_associations_by_class(klass_name)
|
129
|
-
associations_by_class[klass_name.to_s]
|
130
|
-
end
|
139
|
+
def classes(klass)
|
140
|
+
self.class.send(:classes, klass)
|
141
|
+
end
|
131
142
|
|
132
|
-
|
133
|
-
|
134
|
-
|
143
|
+
private :classes
|
144
|
+
|
145
|
+
attr_reader :associations, :types, :attributes
|
146
|
+
attr_accessor :_create_caller_locations
|
147
|
+
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
148
|
+
# attributes but not yet saved (pass a hash with key names matching the associated table column names).
|
149
|
+
# In both instances, valid attribute keys are determined by the column names of the associated table --
|
150
|
+
# hence you can't have attributes that aren't part of the table columns.
|
151
|
+
#
|
152
|
+
# ==== Example:
|
153
|
+
# # Instantiates a single new object
|
154
|
+
# UserMock.new(first_name: 'Jamie')
|
155
|
+
def initialize(attributes = {}, &block)
|
156
|
+
if self.class.abstract_class?
|
157
|
+
raise NotImplementedError, "#{self.class.name} is an abstract class and cannot be instantiated."
|
158
|
+
end
|
159
|
+
setup_instance_variables
|
160
|
+
assign_attributes(attributes, &block)
|
161
|
+
end
|
135
162
|
|
136
|
-
|
163
|
+
def setup_instance_variables
|
164
|
+
@types = self.class.send(:types)
|
165
|
+
@attributes = self.class.send(:attributes).dup
|
166
|
+
@associations = self.class.send(:associations).dup
|
167
|
+
end
|
137
168
|
|
138
|
-
|
169
|
+
private :setup_instance_variables
|
139
170
|
|
140
|
-
|
141
|
-
|
142
|
-
|
171
|
+
def update(attributes={})
|
172
|
+
assign_attributes(attributes)
|
173
|
+
end
|
143
174
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
def initialize(attributes = {}, &block)
|
157
|
-
if self.class.abstract_class?
|
158
|
-
raise NotImplementedError, "#{self.class.name} is an abstract class and cannot be instantiated."
|
159
|
-
end
|
160
|
-
setup_instance_variables
|
161
|
-
assign_attributes(attributes, &block)
|
162
|
-
end
|
175
|
+
# @api private
|
176
|
+
def assign_attributes(new_attributes, &block)
|
177
|
+
yield self if block_given?
|
178
|
+
unless new_attributes.respond_to?(:stringify_keys)
|
179
|
+
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
|
180
|
+
end
|
181
|
+
return nil if new_attributes.blank?
|
182
|
+
attributes = new_attributes.stringify_keys
|
183
|
+
attributes.each do |k, v|
|
184
|
+
_assign_attribute(k, v)
|
185
|
+
end
|
186
|
+
end
|
163
187
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
188
|
+
alias attributes= assign_attributes
|
189
|
+
|
190
|
+
# @api private
|
191
|
+
def _assign_attribute(k, v)
|
192
|
+
public_send("#{k}=", v)
|
193
|
+
rescue NoMethodError
|
194
|
+
if respond_to?("#{k}=")
|
195
|
+
raise
|
196
|
+
else
|
197
|
+
raise UnknownAttributeError.new(self, k)
|
198
|
+
end
|
199
|
+
end
|
169
200
|
|
170
|
-
|
201
|
+
def save(*args)
|
202
|
+
unless self.class.exists?(self)
|
203
|
+
self.class.send(:insert, self)
|
204
|
+
end
|
205
|
+
true
|
206
|
+
end
|
171
207
|
|
172
|
-
|
173
|
-
assign_attributes(attributes)
|
174
|
-
end
|
208
|
+
alias save! save
|
175
209
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
unless new_attributes.respond_to?(:stringify_keys)
|
180
|
-
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
|
181
|
-
end
|
182
|
-
return nil if new_attributes.blank?
|
183
|
-
attributes = new_attributes.stringify_keys
|
184
|
-
attributes.each do |k, v|
|
185
|
-
_assign_attribute(k, v)
|
186
|
-
end
|
187
|
-
end
|
210
|
+
def records
|
211
|
+
self.class.send(:records)
|
212
|
+
end
|
188
213
|
|
189
|
-
|
214
|
+
private :records
|
190
215
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
rescue NoMethodError
|
195
|
-
if respond_to?("#{k}=")
|
196
|
-
raise
|
197
|
-
else
|
198
|
-
raise UnknownAttributeError.new(self, k)
|
199
|
-
end
|
200
|
-
end
|
216
|
+
def delete
|
217
|
+
records.delete(self)
|
218
|
+
end
|
201
219
|
|
202
|
-
|
203
|
-
unless self.class.exists?(self)
|
204
|
-
self.class.send(:insert, self)
|
205
|
-
end
|
206
|
-
true
|
207
|
-
end
|
220
|
+
alias_method :destroy, :delete
|
208
221
|
|
209
|
-
|
222
|
+
delegate :[], :[]=, to: :attributes
|
210
223
|
|
211
|
-
|
212
|
-
|
213
|
-
|
224
|
+
# Returns true if this object hasn't been saved yet; otherwise, returns false.
|
225
|
+
def new_record?
|
226
|
+
records.new_record?(self)
|
227
|
+
end
|
214
228
|
|
215
|
-
|
229
|
+
# Indicates if the model is persisted. Default is +false+.
|
230
|
+
#
|
231
|
+
# person = Person.new(id: 1, name: 'bob')
|
232
|
+
# person.persisted? # => false
|
233
|
+
def persisted?
|
234
|
+
records.persisted?(id)
|
235
|
+
end
|
216
236
|
|
237
|
+
# Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
|
238
|
+
#
|
239
|
+
# person = Person.new
|
240
|
+
# person.has_attribute?(:name) # => true
|
241
|
+
# person.has_attribute?('age') # => true
|
242
|
+
# person.has_attribute?(:nothing) # => false
|
243
|
+
def has_attribute?(attr_name)
|
244
|
+
@attributes.has_key?(attr_name.to_s)
|
245
|
+
end
|
217
246
|
|
218
|
-
|
219
|
-
|
220
|
-
|
247
|
+
# Returns +true+ if the specified +attribute+ has been set and is neither +nil+ nor <tt>empty?</tt> (the latter only applies
|
248
|
+
# to objects that respond to <tt>empty?</tt>, most notably Strings). Otherwise, +false+.
|
249
|
+
# Note that it always returns +true+ with boolean attributes.
|
250
|
+
#
|
251
|
+
# person = Task.new(title: '', is_done: false)
|
252
|
+
# person.attribute_present?(:title) # => false
|
253
|
+
# person.attribute_present?(:is_done) # => true
|
254
|
+
# person.name = 'Francesco'
|
255
|
+
# person.is_done = true
|
256
|
+
# person.attribute_present?(:title) # => true
|
257
|
+
# person.attribute_present?(:is_done) # => true
|
258
|
+
def attribute_present?(attribute)
|
259
|
+
value = read_attribute(attribute)
|
260
|
+
!value.nil? && !(value.respond_to?(:empty?) && value.empty?)
|
261
|
+
end
|
221
262
|
|
222
|
-
|
263
|
+
# Returns an array of names for the attributes available on this object.
|
264
|
+
#
|
265
|
+
# person = Person.new
|
266
|
+
# person.attribute_names
|
267
|
+
# # => ["id", "created_at", "updated_at", "name", "age"]
|
268
|
+
def attribute_names
|
269
|
+
self.class.attribute_names
|
270
|
+
end
|
223
271
|
|
224
|
-
|
272
|
+
def inspect
|
273
|
+
ObjectInspect.new(self.class.name, attributes).to_s
|
274
|
+
end
|
225
275
|
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
276
|
+
# Will not allow attributes to be changed
|
277
|
+
#
|
278
|
+
# Will freeze attributes forever. Querying for the record again will not unfreeze it because records exist in memory
|
279
|
+
# and are not initialized upon a query. This behaviour differs from ActiveRecord, beware of any side effect this may
|
280
|
+
# have when using this method.
|
281
|
+
def freeze
|
282
|
+
@attributes.freeze; self
|
283
|
+
end
|
230
284
|
|
231
|
-
|
232
|
-
#
|
233
|
-
# person = Person.new(id: 1, name: 'bob')
|
234
|
-
# person.persisted? # => false
|
235
|
-
def persisted?
|
236
|
-
records.persisted?(id)
|
237
|
-
end
|
285
|
+
module PropertiesGetterAndSetter
|
238
286
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
def has_attribute?(attr_name)
|
246
|
-
@attributes.has_key?(attr_name.to_s)
|
247
|
-
end
|
287
|
+
# Returns the value of the attribute identified by <tt>attr_name</tt> after
|
288
|
+
# it has been typecast (for example, "2004-12-12" in a date column is cast
|
289
|
+
# to a date object, like Date.new(2004, 12, 12))
|
290
|
+
def read_attribute(attr)
|
291
|
+
@attributes[attr]
|
292
|
+
end
|
248
293
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
# person.attribute_present?(:is_done) # => true
|
256
|
-
# person.name = 'Francesco'
|
257
|
-
# person.is_done = true
|
258
|
-
# person.attribute_present?(:title) # => true
|
259
|
-
# person.attribute_present?(:is_done) # => true
|
260
|
-
def attribute_present?(attribute)
|
261
|
-
value = read_attribute(attribute)
|
262
|
-
!value.nil? && !(value.respond_to?(:empty?) && value.empty?)
|
263
|
-
end
|
294
|
+
# Updates the attribute identified by <tt>attr_name</tt> with the
|
295
|
+
# specified +value+. Empty strings for fixnum and float columns are
|
296
|
+
# turned into +nil+.
|
297
|
+
def write_attribute(attr, value)
|
298
|
+
@attributes[attr] = types[attr].coerce(value)
|
299
|
+
end
|
264
300
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
# # => ["id", "created_at", "updated_at", "name", "age"]
|
270
|
-
def attribute_names
|
271
|
-
self.class.attribute_names
|
272
|
-
end
|
301
|
+
# @api private
|
302
|
+
def read_association(attr, assign_if_value_nil=nil)
|
303
|
+
@associations[attr.to_sym] ||= assign_if_value_nil.try(:call)
|
304
|
+
end
|
273
305
|
|
274
|
-
|
275
|
-
|
276
|
-
|
306
|
+
# @api private
|
307
|
+
def write_association(attr, value)
|
308
|
+
@associations[attr.to_sym] = value
|
309
|
+
end
|
277
310
|
|
278
|
-
|
279
|
-
#
|
280
|
-
# Will freeze attributes forever. Querying for the record again will not unfreeze it because records exist in memory
|
281
|
-
# and are not initialized upon a query. This behaviour differs from ActiveRecord, beware of any side effect this may
|
282
|
-
# have when using this method.
|
283
|
-
def freeze
|
284
|
-
@attributes.freeze; self
|
285
|
-
end
|
311
|
+
protected :read_attribute, :write_attribute, :read_association, :write_association
|
286
312
|
|
287
|
-
|
313
|
+
end
|
288
314
|
|
289
|
-
|
290
|
-
# it has been typecast (for example, "2004-12-12" in a date column is cast
|
291
|
-
# to a date object, like Date.new(2004, 12, 12))
|
292
|
-
def read_attribute(attr)
|
293
|
-
@attributes[attr]
|
294
|
-
end
|
315
|
+
include PropertiesGetterAndSetter
|
295
316
|
|
296
|
-
|
297
|
-
|
298
|
-
# turned into +nil+.
|
299
|
-
def write_attribute(attr, value)
|
300
|
-
@attributes[attr] = types[attr].coerce(value)
|
301
|
-
end
|
317
|
+
class ScopeRelation < Association
|
318
|
+
end
|
302
319
|
|
303
|
-
|
304
|
-
|
305
|
-
@associations[attr.to_sym] ||= assign_if_value_nil.try(:call)
|
306
|
-
end
|
320
|
+
module Scopes
|
321
|
+
end
|
307
322
|
|
308
|
-
# @api private
|
309
|
-
def write_association(attr, value)
|
310
|
-
@associations[attr.to_sym] = value
|
311
323
|
end
|
312
|
-
|
313
|
-
protected :read_attribute, :write_attribute, :read_association, :write_association
|
314
|
-
|
315
|
-
end
|
316
|
-
|
317
|
-
include PropertiesGetterAndSetter
|
318
|
-
|
319
|
-
class ScopeRelation < ::ActiveMocker::Mock::Association
|
320
324
|
end
|
321
|
-
|
322
|
-
module Scopes
|
323
|
-
|
324
|
-
end
|
325
|
-
|
326
|
-
end
|
327
|
-
|
328
|
-
end
|
329
325
|
end
|