@@ -7,47 +7,56 @@ class Model
77 include ActiveModel ::Model
88
99 class_attribute :attribute_names
10+ # Initialize +attribute_names+ for all subclasses. The array is usually
11+ # mutated in the +attributes+ method, but can be set directly, as well.
1012 self . attribute_names = [ ]
1113
1214 def self . attributes ( *names )
13- attr_accessor ( *names )
14- self . attribute_names = attribute_names | names . map ( &:to_sym )
15+ self . attribute_names |= names . map ( &:to_sym )
16+ # Silence redefinition of methods warnings
17+ ActiveModelSerializers . silence_warnings do
18+ attr_accessor ( *names )
19+ end
1520 end
1621
17- attributes :id
18- attr_writer :updated_at
19-
2022 attr_reader :errors
23+ # NOTE that +updated_at+ isn't included in +attribute_names+,
24+ # which means it won't show up in +attributes+ unless a subclass has
25+ # either <tt>attributes :updated_at</tt> which will redefine the methods
26+ # or <tt>attribute_names << :updated_at</tt>.
27+ attr_writer :updated_at
28+ # NOTE that +id+ will always be in +attributes+.
29+ attributes :id
2130
2231 def initialize ( attributes = { } )
2332 @errors = ActiveModel ::Errors . new ( self )
2433 super
2534 end
2635
27- # Defaults to the downcased model name.
28- def id
29- @id ||= self . class . name && self . class . name . downcase
36+ # The the fields in +attribute_names+ determines the returned hash.
37+ # +attributes+ are returned frozen to prevent any expectations that mutation affects
38+ # the actual values in the model.
39+ def attributes
40+ attribute_names . each_with_object ( { } ) do |attribute_name , result |
41+ result [ attribute_name ] = public_send ( attribute_name ) . freeze
42+ end . with_indifferent_access . freeze
3043 end
3144
32- # Defaults to the downcased model name and updated_at
45+ # To customize model behavior, this method must be redefined. However,
46+ # there are other ways of setting the +cache_key+ a serializer uses.
3347 def cache_key
3448 ActiveSupport ::Cache . expand_cache_key ( [
35- self . class . name && self . class . name . downcase ,
49+ self . class . model_name . name . downcase ,
3650 "#{ id } -#{ updated_at . strftime ( '%Y%m%d%H%M%S%9N' ) } "
3751 ] . compact )
3852 end
3953
40- # Defaults to the time the serializer file was modified.
54+ # When no set, defaults to the time the file was modified.
55+ # See NOTE by attr_writer :updated_at
4156 def updated_at
4257 defined? ( @updated_at ) ? @updated_at : File . mtime ( __FILE__ )
4358 end
4459
45- def attributes
46- attribute_names . each_with_object ( { } ) do |attribute_name , result |
47- result [ attribute_name ] = public_send ( attribute_name ) . freeze
48- end . with_indifferent_access . freeze
49- end
50-
5160 # The following methods are needed to be minimally implemented for ActiveModel::Errors
5261 # :nocov:
5362 def self . human_attribute_name ( attr , _options = { } )
0 commit comments