active_model_serializers 0.10.4 → 0.10.5
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/.travis.yml +7 -3
- data/CHANGELOG.md +25 -1
- data/README.md +4 -4
- data/active_model_serializers.gemspec +1 -1
- data/appveyor.yml +9 -3
- data/docs/general/logging.md +7 -0
- data/docs/general/serializers.md +3 -3
- data/docs/howto/add_pagination_links.md +13 -13
- data/docs/howto/add_relationship_links.md +24 -21
- data/docs/howto/outside_controller_use.md +3 -2
- data/docs/howto/serialize_poro.md +46 -5
- data/docs/howto/upgrade_from_0_8_to_0_10.md +1 -1
- data/lib/active_model/serializer/version.rb +1 -1
- data/lib/active_model_serializers.rb +8 -0
- data/lib/active_model_serializers/model.rb +108 -30
- data/lib/active_model_serializers/test/schema.rb +2 -2
- data/lib/generators/rails/resource_override.rb +1 -1
- data/test/action_controller/adapter_selector_test.rb +11 -2
- data/test/action_controller/json_api/fields_test.rb +15 -6
- data/test/action_controller/json_api/transform_test.rb +11 -3
- data/test/action_controller/namespace_lookup_test.rb +14 -8
- data/test/action_controller/serialization_scope_name_test.rb +12 -6
- data/test/action_controller/serialization_test.rb +1 -1
- data/test/active_model_serializers/model_test.rb +122 -2
- data/test/active_model_serializers/railtie_test_isolated.rb +12 -7
- data/test/active_model_serializers/register_jsonapi_renderer_test_isolated.rb +37 -19
- data/test/adapter/attributes_test.rb +2 -5
- data/test/adapter/json/has_many_test.rb +10 -2
- data/test/adapter/json_api/fields_test.rb +11 -3
- data/test/adapter/json_api/has_many_test.rb +10 -2
- data/test/adapter/json_api/include_data_if_sideloaded_test.rb +22 -5
- data/test/adapter/json_api/linked_test.rb +3 -3
- data/test/adapter/json_api/links_test.rb +1 -1
- data/test/adapter/json_api/relationship_test.rb +1 -1
- data/test/adapter/json_api/transform_test.rb +11 -3
- data/test/cache_test.rb +100 -28
- data/test/collection_serializer_test.rb +23 -10
- data/test/fixtures/active_record.rb +45 -10
- data/test/fixtures/poro.rb +115 -176
- data/test/generators/serializer_generator_test.rb +1 -0
- data/test/grape_test.rb +20 -2
- data/test/serializers/associations_test.rb +28 -7
- data/test/serializers/attribute_test.rb +4 -2
- data/test/serializers/caching_configuration_test_isolated.rb +6 -6
- data/test/serializers/options_test.rb +17 -6
- data/test/serializers/read_attribute_for_serialization_test.rb +3 -3
- data/test/serializers/serialization_test.rb +2 -2
- data/test/serializers/serializer_for_test.rb +6 -6
- data/test/serializers/serializer_for_with_namespace_test.rb +6 -5
- data/test/support/rails_app.rb +2 -0
- data/test/test_helper.rb +12 -0
- metadata +13 -7
@@ -1,51 +1,129 @@
|
|
1
|
-
# ActiveModelSerializers::Model is a convenient
|
2
|
-
#
|
3
|
-
#
|
1
|
+
# ActiveModelSerializers::Model is a convenient superclass for making your models
|
2
|
+
# from Plain-Old Ruby Objects (PORO). It also serves as a reference implementation
|
3
|
+
# that satisfies ActiveModel::Serializer::Lint::Tests.
|
4
4
|
module ActiveModelSerializers
|
5
5
|
class Model
|
6
|
-
include ActiveModel::Model
|
7
6
|
include ActiveModel::Serializers::JSON
|
7
|
+
include ActiveModel::Model
|
8
8
|
|
9
|
-
|
9
|
+
# Declare names of attributes to be included in +sttributes+ hash.
|
10
|
+
# Is only available as a class-method since the ActiveModel::Serialization mixin in Rails
|
11
|
+
# uses an +attribute_names+ local variable, which may conflict if we were to add instance methods here.
|
12
|
+
#
|
13
|
+
# @overload attribute_names
|
14
|
+
# @return [Array<Symbol>]
|
15
|
+
class_attribute :attribute_names, instance_writer: false, instance_reader: false
|
16
|
+
# Initialize +attribute_names+ for all subclasses. The array is usually
|
17
|
+
# mutated in the +attributes+ method, but can be set directly, as well.
|
18
|
+
self.attribute_names = []
|
10
19
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
20
|
+
# Easily declare instance attributes with setters and getters for each.
|
21
|
+
#
|
22
|
+
# All attributes to initialize an instance must have setters.
|
23
|
+
# However, the hash turned by +attributes+ instance method will ALWAYS
|
24
|
+
# be the value of the initial attributes, regardless of what accessors are defined.
|
25
|
+
# The only way to change the change the attributes after initialization is
|
26
|
+
# to mutate the +attributes+ directly.
|
27
|
+
# Accessor methods do NOT mutate the attributes. (This is a bug).
|
28
|
+
#
|
29
|
+
# @note For now, the Model only supports the notion of 'attributes'.
|
30
|
+
# In the tests, there is a special Model that also supports 'associations'. This is
|
31
|
+
# important so that we can add accessors for values that should not appear in the
|
32
|
+
# attributes hash when modeling associations. It is not yet clear if it
|
33
|
+
# makes sense for a PORO to have associations outside of the tests.
|
34
|
+
#
|
35
|
+
# @overload attributes(names)
|
36
|
+
# @param names [Array<String, Symbol>]
|
37
|
+
# @param name [String, Symbol]
|
38
|
+
def self.attributes(*names)
|
39
|
+
self.attribute_names |= names.map(&:to_sym)
|
40
|
+
# Silence redefinition of methods warnings
|
41
|
+
ActiveModelSerializers.silence_warnings do
|
42
|
+
attr_accessor(*names)
|
43
|
+
end
|
15
44
|
end
|
16
45
|
|
17
|
-
#
|
18
|
-
def
|
19
|
-
|
46
|
+
# Opt-in to breaking change
|
47
|
+
def self.derive_attributes_from_names_and_fix_accessors
|
48
|
+
unless included_modules.include?(DeriveAttributesFromNamesAndFixAccessors)
|
49
|
+
prepend(DeriveAttributesFromNamesAndFixAccessors)
|
50
|
+
end
|
20
51
|
end
|
21
52
|
|
22
|
-
|
23
|
-
|
24
|
-
|
53
|
+
module DeriveAttributesFromNamesAndFixAccessors
|
54
|
+
def self.included(base)
|
55
|
+
# NOTE that +id+ will always be in +attributes+.
|
56
|
+
base.attributes :id
|
57
|
+
end
|
58
|
+
|
59
|
+
# Override the +attributes+ method so that the hash is derived from +attribute_names+.
|
60
|
+
#
|
61
|
+
# The the fields in +attribute_names+ determines the returned hash.
|
62
|
+
# +attributes+ are returned frozen to prevent any expectations that mutation affects
|
63
|
+
# the actual values in the model.
|
64
|
+
def attributes
|
65
|
+
self.class.attribute_names.each_with_object({}) do |attribute_name, result|
|
66
|
+
result[attribute_name] = public_send(attribute_name).freeze
|
67
|
+
end.with_indifferent_access.freeze
|
68
|
+
end
|
25
69
|
end
|
26
70
|
|
27
|
-
#
|
28
|
-
|
29
|
-
|
71
|
+
# Support for validation and other ActiveModel::Errors
|
72
|
+
# @return [ActiveModel::Errors]
|
73
|
+
attr_reader :errors
|
74
|
+
|
75
|
+
# (see #updated_at)
|
76
|
+
attr_writer :updated_at
|
77
|
+
|
78
|
+
# The only way to change the attributes of an instance is to directly mutate the attributes.
|
79
|
+
# @example
|
80
|
+
#
|
81
|
+
# model.attributes[:foo] = :bar
|
82
|
+
# @return [Hash]
|
83
|
+
attr_reader :attributes
|
84
|
+
|
85
|
+
# @param attributes [Hash]
|
86
|
+
def initialize(attributes = {})
|
87
|
+
attributes ||= {} # protect against nil
|
88
|
+
@attributes = attributes.symbolize_keys.with_indifferent_access
|
89
|
+
@errors = ActiveModel::Errors.new(self)
|
90
|
+
super
|
30
91
|
end
|
31
92
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
93
|
+
# Defaults to the downcased model name.
|
94
|
+
# This probably isn't a good default, since it's not a unique instance identifier,
|
95
|
+
# but that's what is currently implemented \_('-')_/.
|
96
|
+
#
|
97
|
+
# @note Though +id+ is defined, it will only show up
|
98
|
+
# in +attributes+ when it is passed in to the initializer or added to +attributes+,
|
99
|
+
# such as <tt>attributes[:id] = 5</tt>.
|
100
|
+
# @return [String, Numeric, Symbol]
|
101
|
+
def id
|
102
|
+
attributes.fetch(:id) do
|
103
|
+
defined?(@id) ? @id : self.class.model_name.name && self.class.model_name.name.downcase
|
37
104
|
end
|
38
105
|
end
|
39
106
|
|
40
|
-
#
|
41
|
-
#
|
42
|
-
|
43
|
-
|
107
|
+
# When not set, defaults to the time the file was modified.
|
108
|
+
#
|
109
|
+
# @note Though +updated_at+ and +updated_at=+ are defined, it will only show up
|
110
|
+
# in +attributes+ when it is passed in to the initializer or added to +attributes+,
|
111
|
+
# such as <tt>attributes[:updated_at] = Time.current</tt>.
|
112
|
+
# @return [String, Numeric, Time]
|
113
|
+
def updated_at
|
114
|
+
attributes.fetch(:updated_at) do
|
115
|
+
defined?(@updated_at) ? @updated_at : File.mtime(__FILE__)
|
116
|
+
end
|
44
117
|
end
|
45
118
|
|
46
|
-
|
47
|
-
|
119
|
+
# To customize model behavior, this method must be redefined. However,
|
120
|
+
# there are other ways of setting the +cache_key+ a serializer uses.
|
121
|
+
# @return [String]
|
122
|
+
def cache_key
|
123
|
+
ActiveSupport::Cache.expand_cache_key([
|
124
|
+
self.class.model_name.name.downcase,
|
125
|
+
"#{id}-#{updated_at.strftime('%Y%m%d%H%M%S%9N')}"
|
126
|
+
].compact)
|
48
127
|
end
|
49
|
-
# :nocov:
|
50
128
|
end
|
51
129
|
end
|
@@ -60,11 +60,11 @@ module ActiveModelSerializers
|
|
60
60
|
attr_reader :document_store
|
61
61
|
|
62
62
|
def controller_path
|
63
|
-
request.filtered_parameters[:controller]
|
63
|
+
request.filtered_parameters.with_indifferent_access[:controller]
|
64
64
|
end
|
65
65
|
|
66
66
|
def action
|
67
|
-
request.filtered_parameters[:action]
|
67
|
+
request.filtered_parameters.with_indifferent_access[:action]
|
68
68
|
end
|
69
69
|
|
70
70
|
def schema_directory
|
@@ -3,6 +3,15 @@ require 'test_helper'
|
|
3
3
|
module ActionController
|
4
4
|
module Serialization
|
5
5
|
class AdapterSelectorTest < ActionController::TestCase
|
6
|
+
class Profile < Model
|
7
|
+
attributes :id, :name, :description
|
8
|
+
associations :comments
|
9
|
+
end
|
10
|
+
class ProfileSerializer < ActiveModel::Serializer
|
11
|
+
type 'profiles'
|
12
|
+
attributes :name, :description
|
13
|
+
end
|
14
|
+
|
6
15
|
class AdapterSelectorTestController < ActionController::Base
|
7
16
|
def render_using_default_adapter
|
8
17
|
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
@@ -15,7 +24,7 @@ module ActionController
|
|
15
24
|
end
|
16
25
|
|
17
26
|
def render_skipping_adapter
|
18
|
-
@profile = Profile.new(name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
27
|
+
@profile = Profile.new(id: 'render_skipping_adapter_id', name: 'Name 1', description: 'Description 1', comments: 'Comments 1')
|
19
28
|
render json: @profile, adapter: false
|
20
29
|
end
|
21
30
|
end
|
@@ -46,7 +55,7 @@ module ActionController
|
|
46
55
|
|
47
56
|
def test_render_skipping_adapter
|
48
57
|
get :render_skipping_adapter
|
49
|
-
assert_equal '{"
|
58
|
+
assert_equal '{"id":"render_skipping_adapter_id","name":"Name 1","description":"Description 1"}', response.body
|
50
59
|
end
|
51
60
|
end
|
52
61
|
end
|
@@ -5,7 +5,16 @@ module ActionController
|
|
5
5
|
class JsonApi
|
6
6
|
class FieldsTest < ActionController::TestCase
|
7
7
|
class FieldsTestController < ActionController::Base
|
8
|
-
class
|
8
|
+
class AuthorWithName < Author
|
9
|
+
attributes :first_name, :last_name
|
10
|
+
end
|
11
|
+
class AuthorWithNameSerializer < AuthorSerializer
|
12
|
+
type 'authors'
|
13
|
+
end
|
14
|
+
class PostWithPublishAt < Post
|
15
|
+
attributes :publish_at
|
16
|
+
end
|
17
|
+
class PostWithPublishAtSerializer < ActiveModel::Serializer
|
9
18
|
type 'posts'
|
10
19
|
attributes :title, :body, :publish_at
|
11
20
|
belongs_to :author
|
@@ -14,19 +23,19 @@ module ActionController
|
|
14
23
|
|
15
24
|
def setup_post
|
16
25
|
ActionController::Base.cache_store.clear
|
17
|
-
@author =
|
26
|
+
@author = AuthorWithName.new(id: 1, first_name: 'Bob', last_name: 'Jones')
|
18
27
|
@comment1 = Comment.new(id: 7, body: 'cool', author: @author)
|
19
28
|
@comment2 = Comment.new(id: 12, body: 'awesome', author: @author)
|
20
|
-
@post =
|
21
|
-
|
22
|
-
|
29
|
+
@post = PostWithPublishAt.new(id: 1337, title: 'Title 1', body: 'Body 1',
|
30
|
+
author: @author, comments: [@comment1, @comment2],
|
31
|
+
publish_at: '2020-03-16T03:55:25.291Z')
|
23
32
|
@comment1.post = @post
|
24
33
|
@comment2.post = @post
|
25
34
|
end
|
26
35
|
|
27
36
|
def render_fields_works_on_relationships
|
28
37
|
setup_post
|
29
|
-
render json: @post, serializer:
|
38
|
+
render json: @post, serializer: PostWithPublishAtSerializer, adapter: :json_api, fields: { posts: [:author] }
|
30
39
|
end
|
31
40
|
end
|
32
41
|
|
@@ -5,9 +5,17 @@ module ActionController
|
|
5
5
|
class JsonApi
|
6
6
|
class KeyTransformTest < ActionController::TestCase
|
7
7
|
class KeyTransformTestController < ActionController::Base
|
8
|
-
class Post < ::Model
|
9
|
-
|
10
|
-
|
8
|
+
class Post < ::Model
|
9
|
+
attributes :title, :body, :publish_at
|
10
|
+
associations :author, :top_comments
|
11
|
+
end
|
12
|
+
class Author < ::Model
|
13
|
+
attributes :first_name, :last_name
|
14
|
+
end
|
15
|
+
class TopComment < ::Model
|
16
|
+
attributes :body
|
17
|
+
associations :author, :post
|
18
|
+
end
|
11
19
|
class PostSerializer < ActiveModel::Serializer
|
12
20
|
type 'posts'
|
13
21
|
attributes :title, :body, :publish_at
|
@@ -3,10 +3,16 @@ require 'test_helper'
|
|
3
3
|
module ActionController
|
4
4
|
module Serialization
|
5
5
|
class NamespaceLookupTest < ActionController::TestCase
|
6
|
-
class Book < ::Model
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
class Book < ::Model
|
7
|
+
attributes :id, :title, :body
|
8
|
+
associations :writer, :chapters
|
9
|
+
end
|
10
|
+
class Chapter < ::Model
|
11
|
+
attributes :title
|
12
|
+
end
|
13
|
+
class Writer < ::Model
|
14
|
+
attributes :name
|
15
|
+
end
|
10
16
|
|
11
17
|
module Api
|
12
18
|
module V2
|
@@ -80,7 +86,7 @@ module ActionController
|
|
80
86
|
book = Book.new(title: 'New Post', body: 'Body')
|
81
87
|
|
82
88
|
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
83
|
-
# the
|
89
|
+
# the lookup thinks we mean ::Api::V2
|
84
90
|
render json: book, namespace: 'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
85
91
|
end
|
86
92
|
|
@@ -88,12 +94,12 @@ module ActionController
|
|
88
94
|
book = Book.new(title: 'New Post', body: 'Body')
|
89
95
|
|
90
96
|
# because this is a string, ruby can't auto-lookup the constant, so otherwise
|
91
|
-
# the
|
97
|
+
# the lookup thinks we mean ::Api::V2
|
92
98
|
render json: book, namespace: :'ActionController::Serialization::NamespaceLookupTest::Api::V2'
|
93
99
|
end
|
94
100
|
|
95
101
|
def invalid_namespace
|
96
|
-
book = Book.new(title: 'New Post', body: 'Body')
|
102
|
+
book = Book.new(id: 'invalid_namespace_book_id', title: 'New Post', body: 'Body')
|
97
103
|
|
98
104
|
render json: book, namespace: :api_v2
|
99
105
|
end
|
@@ -205,7 +211,7 @@ module ActionController
|
|
205
211
|
|
206
212
|
assert_serializer ActiveModel::Serializer::Null
|
207
213
|
|
208
|
-
expected = { 'title' => 'New Post', 'body' => 'Body' }
|
214
|
+
expected = { 'id' => 'invalid_namespace_book_id', 'title' => 'New Post', 'body' => 'Body' }
|
209
215
|
actual = JSON.parse(@response.body)
|
210
216
|
|
211
217
|
assert_equal expected, actual
|
@@ -2,16 +2,16 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
module SerializationScopeTesting
|
4
4
|
class User < ActiveModelSerializers::Model
|
5
|
-
|
5
|
+
attributes :id, :name, :admin
|
6
6
|
def admin?
|
7
7
|
admin
|
8
8
|
end
|
9
9
|
end
|
10
10
|
class Comment < ActiveModelSerializers::Model
|
11
|
-
|
11
|
+
attributes :id, :body
|
12
12
|
end
|
13
13
|
class Post < ActiveModelSerializers::Model
|
14
|
-
|
14
|
+
attributes :id, :title, :body, :comments
|
15
15
|
end
|
16
16
|
class PostSerializer < ActiveModel::Serializer
|
17
17
|
attributes :id, :title, :body, :comments
|
@@ -33,7 +33,8 @@ module SerializationScopeTesting
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
class PostTestController < ActionController::Base
|
36
|
-
|
36
|
+
attr_writer :current_user
|
37
|
+
|
37
38
|
def render_post_by_non_admin
|
38
39
|
self.current_user = User.new(id: 3, name: 'Pete', admin: false)
|
39
40
|
render json: new_post, serializer: serializer, adapter: :json
|
@@ -44,6 +45,10 @@ module SerializationScopeTesting
|
|
44
45
|
render json: new_post, serializer: serializer, adapter: :json
|
45
46
|
end
|
46
47
|
|
48
|
+
def current_user
|
49
|
+
defined?(@current_user) ? @current_user : :current_user_not_set
|
50
|
+
end
|
51
|
+
|
47
52
|
private
|
48
53
|
|
49
54
|
def new_post
|
@@ -75,7 +80,8 @@ module SerializationScopeTesting
|
|
75
80
|
end
|
76
81
|
|
77
82
|
def test_default_serialization_scope_object
|
78
|
-
assert_equal
|
83
|
+
assert_equal :current_user_not_set, @controller.current_user
|
84
|
+
assert_equal :current_user_not_set, @controller.serialization_scope
|
79
85
|
end
|
80
86
|
|
81
87
|
def test_default_scope_non_admin
|
@@ -125,7 +131,7 @@ module SerializationScopeTesting
|
|
125
131
|
end
|
126
132
|
|
127
133
|
def test_defined_serialization_scope_object
|
128
|
-
assert_equal @controller.view_context.
|
134
|
+
assert_equal @controller.view_context.controller, @controller.serialization_scope.controller
|
129
135
|
end
|
130
136
|
|
131
137
|
def test_serialization_scope_non_admin
|
@@ -4,13 +4,13 @@ module ActiveModelSerializers
|
|
4
4
|
class ModelTest < ActiveSupport::TestCase
|
5
5
|
include ActiveModel::Serializer::Lint::Tests
|
6
6
|
|
7
|
-
|
7
|
+
setup do
|
8
8
|
@resource = ActiveModelSerializers::Model.new
|
9
9
|
end
|
10
10
|
|
11
11
|
def test_initialization_with_string_keys
|
12
12
|
klass = Class.new(ActiveModelSerializers::Model) do
|
13
|
-
|
13
|
+
attributes :key
|
14
14
|
end
|
15
15
|
value = 'value'
|
16
16
|
|
@@ -18,5 +18,125 @@ module ActiveModelSerializers
|
|
18
18
|
|
19
19
|
assert_equal model_instance.read_attribute_for_serialization(:key), value
|
20
20
|
end
|
21
|
+
|
22
|
+
def test_attributes_can_be_read_for_serialization
|
23
|
+
klass = Class.new(ActiveModelSerializers::Model) do
|
24
|
+
attributes :one, :two, :three
|
25
|
+
end
|
26
|
+
original_attributes = { one: 1, two: 2, three: 3 }
|
27
|
+
original_instance = klass.new(original_attributes)
|
28
|
+
|
29
|
+
# Initial value
|
30
|
+
instance = original_instance
|
31
|
+
expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
|
32
|
+
assert_equal expected_attributes, instance.attributes
|
33
|
+
assert_equal 1, instance.one
|
34
|
+
assert_equal 1, instance.read_attribute_for_serialization(:one)
|
35
|
+
|
36
|
+
# FIXME: Change via accessor has no effect on attributes.
|
37
|
+
instance = original_instance.dup
|
38
|
+
instance.one = :not_one
|
39
|
+
assert_equal expected_attributes, instance.attributes
|
40
|
+
assert_equal :not_one, instance.one
|
41
|
+
assert_equal :not_one, instance.read_attribute_for_serialization(:one)
|
42
|
+
|
43
|
+
# FIXME: Change via mutating attributes
|
44
|
+
instance = original_instance.dup
|
45
|
+
instance.attributes[:one] = :not_one
|
46
|
+
expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
|
47
|
+
assert_equal expected_attributes, instance.attributes
|
48
|
+
assert_equal 1, instance.one
|
49
|
+
assert_equal 1, instance.read_attribute_for_serialization(:one)
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_attributes_can_be_read_for_serialization_with_attributes_accessors_fix
|
53
|
+
klass = Class.new(ActiveModelSerializers::Model) do
|
54
|
+
derive_attributes_from_names_and_fix_accessors
|
55
|
+
attributes :one, :two, :three
|
56
|
+
end
|
57
|
+
original_attributes = { one: 1, two: 2, three: 3 }
|
58
|
+
original_instance = klass.new(original_attributes)
|
59
|
+
|
60
|
+
# Initial value
|
61
|
+
instance = original_instance
|
62
|
+
expected_attributes = { one: 1, two: 2, three: 3 }.with_indifferent_access
|
63
|
+
assert_equal expected_attributes, instance.attributes
|
64
|
+
assert_equal 1, instance.one
|
65
|
+
assert_equal 1, instance.read_attribute_for_serialization(:one)
|
66
|
+
|
67
|
+
expected_attributes = { one: :not_one, two: 2, three: 3 }.with_indifferent_access
|
68
|
+
# Change via accessor
|
69
|
+
instance = original_instance.dup
|
70
|
+
instance.one = :not_one
|
71
|
+
assert_equal expected_attributes, instance.attributes
|
72
|
+
assert_equal :not_one, instance.one
|
73
|
+
assert_equal :not_one, instance.read_attribute_for_serialization(:one)
|
74
|
+
|
75
|
+
# Attributes frozen
|
76
|
+
assert instance.attributes.frozen?
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_id_attribute_can_be_read_for_serialization
|
80
|
+
klass = Class.new(ActiveModelSerializers::Model) do
|
81
|
+
attributes :id, :one, :two, :three
|
82
|
+
end
|
83
|
+
self.class.const_set(:SomeTestModel, klass)
|
84
|
+
original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
|
85
|
+
original_instance = klass.new(original_attributes)
|
86
|
+
|
87
|
+
# Initial value
|
88
|
+
instance = original_instance.dup
|
89
|
+
expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
|
90
|
+
assert_equal expected_attributes, instance.attributes
|
91
|
+
assert_equal :ego, instance.id
|
92
|
+
assert_equal :ego, instance.read_attribute_for_serialization(:id)
|
93
|
+
|
94
|
+
# FIXME: Change via accessor has no effect on attributes.
|
95
|
+
instance = original_instance.dup
|
96
|
+
instance.id = :superego
|
97
|
+
assert_equal expected_attributes, instance.attributes
|
98
|
+
assert_equal :superego, instance.id
|
99
|
+
assert_equal :superego, instance.read_attribute_for_serialization(:id)
|
100
|
+
|
101
|
+
# FIXME: Change via mutating attributes
|
102
|
+
instance = original_instance.dup
|
103
|
+
instance.attributes[:id] = :superego
|
104
|
+
expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
|
105
|
+
assert_equal expected_attributes, instance.attributes
|
106
|
+
assert_equal :ego, instance.id
|
107
|
+
assert_equal :ego, instance.read_attribute_for_serialization(:id)
|
108
|
+
ensure
|
109
|
+
self.class.send(:remove_const, :SomeTestModel)
|
110
|
+
end
|
111
|
+
|
112
|
+
def test_id_attribute_can_be_read_for_serialization_with_attributes_accessors_fix
|
113
|
+
klass = Class.new(ActiveModelSerializers::Model) do
|
114
|
+
derive_attributes_from_names_and_fix_accessors
|
115
|
+
attributes :id, :one, :two, :three
|
116
|
+
end
|
117
|
+
self.class.const_set(:SomeTestModel, klass)
|
118
|
+
original_attributes = { id: :ego, one: 1, two: 2, three: 3 }
|
119
|
+
original_instance = klass.new(original_attributes)
|
120
|
+
|
121
|
+
# Initial value
|
122
|
+
instance = original_instance.dup
|
123
|
+
expected_attributes = { id: :ego, one: 1, two: 2, three: 3 }.with_indifferent_access
|
124
|
+
assert_equal expected_attributes, instance.attributes
|
125
|
+
assert_equal :ego, instance.id
|
126
|
+
assert_equal :ego, instance.read_attribute_for_serialization(:id)
|
127
|
+
|
128
|
+
expected_attributes = { id: :superego, one: 1, two: 2, three: 3 }.with_indifferent_access
|
129
|
+
# Change via accessor
|
130
|
+
instance = original_instance.dup
|
131
|
+
instance.id = :superego
|
132
|
+
assert_equal expected_attributes, instance.attributes
|
133
|
+
assert_equal :superego, instance.id
|
134
|
+
assert_equal :superego, instance.read_attribute_for_serialization(:id)
|
135
|
+
|
136
|
+
# Attributes frozen
|
137
|
+
assert instance.attributes.frozen?
|
138
|
+
ensure
|
139
|
+
self.class.send(:remove_const, :SomeTestModel)
|
140
|
+
end
|
21
141
|
end
|
22
142
|
end
|