@@ -208,14 +208,30 @@ module ClassMethods
208
208
# tracking is performed. The methods +changed?+ and +changed_in_place?+
209
209
# will be called from ActiveModel::Dirty. See the documentation for those
210
210
# methods in ActiveModel::Type::Value for more details.
211
- def attribute ( name , cast_type = nil , **options , &block )
211
+ def attribute ( name , cast_type = nil , default : NO_DEFAULT_PROVIDED , **options , &block )
212
212
name = name . to_s
213
213
reload_schema_from_cache
214
214
215
+ case cast_type
216
+ when Symbol
217
+ type = cast_type
218
+ cast_type = -> _ { Type . lookup ( type , **options , adapter : Type . adapter_name_from ( self ) ) }
219
+ when nil
220
+ if ( prev_cast_type , prev_default = attributes_to_define_after_schema_loads [ name ] )
221
+ default = prev_default if default == NO_DEFAULT_PROVIDED
222
+
223
+ cast_type = if block_given?
224
+ -> subtype { yield Proc === prev_cast_type ? prev_cast_type [ subtype ] : prev_cast_type }
225
+ else
226
+ prev_cast_type
227
+ end
228
+ else
229
+ cast_type = block || -> subtype { subtype }
230
+ end
231
+ end
232
+
215
233
self . attributes_to_define_after_schema_loads =
216
- attributes_to_define_after_schema_loads . merge (
217
- name => [ cast_type || block , options ]
218
- )
234
+ attributes_to_define_after_schema_loads . merge ( name => [ cast_type , default ] )
219
235
end
220
236
221
237
# This is the low level API which sits beneath +attribute+. It only
@@ -248,8 +264,9 @@ def define_attribute(
248
264
249
265
def load_schema! # :nodoc:
250
266
super
251
- attributes_to_define_after_schema_loads . each do |name , ( type , options ) |
252
- define_attribute ( name , _lookup_cast_type ( name , type , options ) , **options . slice ( :default ) )
267
+ attributes_to_define_after_schema_loads . each do |name , ( cast_type , default ) |
268
+ cast_type = cast_type [ type_for_attribute ( name ) ] if Proc === cast_type
269
+ define_attribute ( name , cast_type , default : default )
253
270
end
254
271
end
255
272
@@ -272,32 +289,6 @@ def define_default_attribute(name, value, type, from_user:)
272
289
end
273
290
_default_attributes [ name ] = default_attribute
274
291
end
275
-
276
- def decorate_attribute_type ( attr_name , **default )
277
- type , options = attributes_to_define_after_schema_loads [ attr_name ]
278
-
279
- default . with_defaults! ( default : options [ :default ] ) if options &.key? ( :default )
280
-
281
- attribute ( attr_name , **default ) do |cast_type |
282
- if type && !type . is_a? ( Proc )
283
- cast_type = _lookup_cast_type ( attr_name , type , options )
284
- end
285
-
286
- yield cast_type
287
- end
288
- end
289
-
290
- def _lookup_cast_type ( name , type , options )
291
- case type
292
- when Symbol
293
- adapter_name = ActiveRecord ::Type . adapter_name_from ( self )
294
- ActiveRecord ::Type . lookup ( type , **options . except ( :default ) , adapter : adapter_name )
295
- when Proc
296
- type [ type_for_attribute ( name ) ]
297
- else
298
- type || type_for_attribute ( name )
299
- end
300
- end
301
292
end
302
293
end
303
294
end
0 commit comments