Skip to content

Commit a9d50f3

Browse files
committed
More cleanup
1 parent f7b3fe6 commit a9d50f3

File tree

5 files changed

+42
-20
lines changed

5 files changed

+42
-20
lines changed

lib/active_model_serializers.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ def self.default_include_directive
3838
@default_include_directive ||= JSONAPI::IncludeDirective.new(config.default_includes, allow_wildcard: true)
3939
end
4040

41+
def self.silence_warnings
42+
original_verbose = $VERBOSE
43+
$VERBOSE = nil
44+
yield
45+
ensure
46+
$VERBOSE = original_verbose
47+
end
48+
4149
require 'active_model/serializer/version'
4250
require 'active_model/serializer'
4351
require 'active_model/serializable_resource'

lib/active_model_serializers/model.rb

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -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 = {})

test/collection_serializer_test.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
module ActiveModel
44
class Serializer
55
class CollectionSerializerTest < ActiveSupport::TestCase
6-
SingularModel = poro_without_caching_support
6+
class SingularModel < ::Model; end
77
class SingularModelSerializer < ActiveModel::Serializer
88
end
9-
HasManyModel = poro_without_caching_support(::Model) do
9+
class HasManyModel < ::Model
1010
associations :singular_models
1111
end
1212
class HasManyModelSerializer < ActiveModel::Serializer

test/fixtures/poro.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33
class Model < ActiveModelSerializers::Model
44
FILE_DIGEST = Digest::MD5.hexdigest(File.open(__FILE__).read)
55

6+
# Defaults to the downcased model name.
7+
def id
8+
@id ||= self.class.model_name.name.downcase
9+
end
10+
611
# At this time, just for organization of intent
712
class_attribute :association_names
813
self.association_names = []

test/serializers/options_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
module ActiveModel
44
class Serializer
55
class OptionsTest < ActiveSupport::TestCase
6-
ModelWithOptions = poro_without_caching_support do
6+
class ModelWithOptions < ActiveModelSerializers::Model
77
attributes :name, :description
88
end
99
class ModelWithOptionsSerializer < ActiveModel::Serializer

0 commit comments

Comments
 (0)