Skip to content

Commit 784799e

Browse files
committed
Test caching with fragmented key
- on association, fix up assocation logic - on attribute
1 parent b892415 commit 784799e

File tree

4 files changed

+52
-34
lines changed

4 files changed

+52
-34
lines changed

lib/active_model/serializer/caching.rb

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ def _skip_digest?
7070

7171
def fragmented_attributes
7272
cached = _cache_only ? _cache_only : _attributes - _cache_except
73-
cached = cached.map! {|field| _attributes_keys.fetch(field, field) }
73+
cached = cached.map! { |field| _attributes_keys.fetch(field, field) }
7474
non_cached = _attributes - cached
75-
non_cached = non_cached.map! {|field| _attributes_keys.fetch(field, field) }
75+
non_cached = non_cached.map! { |field| _attributes_keys.fetch(field, field) }
7676
{
7777
cached: cached,
7878
non_cached: non_cached
@@ -233,28 +233,20 @@ def fetch(adapter_instance, cache_options = self.class._cache_options)
233233
def fetch_attributes_fragment(adapter_instance)
234234
self.class._cache_options ||= {}
235235
self.class._cache_options[:key] = self.class._cache_key if self.class._cache_key
236-
options = { include_directive: ActiveModel::Serializer.include_directive_from_options({})}
237236
fields = self.class.fragmented_attributes
238237

239238
non_cached_fields = fields[:non_cached].dup
240239
non_cached_hash = attributes(non_cached_fields, true)
241-
(non_cached_fields - non_cached_hash.keys).each do |missing_field|
242-
# TODO: use _attributes_keys?
243-
# gets any other associations, etc.
244-
non_cached_hash[missing_field] = read_attribute_for_serialization(missing_field)
245-
end
240+
include_directive = JSONAPI::IncludeDirective.new(non_cached_fields - non_cached_hash.keys)
241+
non_cached_hash.merge! resource_relationships({}, { include_directive: include_directive }, adapter_instance)
246242

247243
cached_fields = fields[:cached].dup
248244
key = cache_key(adapter_instance)
249245
cached_hash =
250246
self.class.cache_store.fetch(key, self.class._cache_options) do
251247
hash = attributes(cached_fields, true)
252-
(cached_fields - hash.keys).each do |missing_field|
253-
# TODO: use _attributes_keys?
254-
# gets any other associations, etc.
255-
hash[missing_field] = read_attribute_for_serialization(missing_field)
256-
end
257-
hash
248+
include_directive = JSONAPI::IncludeDirective.new(cached_fields - hash.keys)
249+
hash.merge! resource_relationships({}, { include_directive: include_directive }, adapter_instance)
258250
end
259251

260252
# Merge both results

test/action_controller/explicit_serializer_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def test_render_using_explicit_each_serializer
123123
id: 42,
124124
lat: '-23.550520',
125125
lng: '-46.633309',
126-
place: 'Nowhere' # is a virtual attribute on LocationSerializer
126+
address: 'Nowhere' # is a virtual attribute on LocationSerializer
127127
}
128128
]
129129
}

test/cache_test.rb

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ def test_cache_options_definition
127127
end
128128

129129
def test_fragment_cache_definition
130-
assert_equal([:name], @role_serializer.class._cache_only)
130+
assert_equal([:name, :slug], @role_serializer.class._cache_only)
131131
assert_equal([:content], @bio_serializer.class._cache_except)
132132
end
133133

@@ -178,14 +178,14 @@ def test_fragment_fetch_with_virtual_associations
178178
id: @location.id,
179179
lat: @location.lat,
180180
lng: @location.lng,
181-
place: 'Nowhere'
181+
address: 'Nowhere'
182182
}
183183

184184
hash = render_object_with_cache(@location)
185185

186186
assert_equal(hash, expected_result)
187187
key = "#{@location.cache_key}/#{adapter.cache_key}"
188-
assert_equal({ place: 'Nowhere' }, cache_store.fetch(key))
188+
assert_equal({ address: 'Nowhere' }, cache_store.fetch(key))
189189
end
190190

191191
def test_fragment_cache_with_inheritance
@@ -434,21 +434,46 @@ def test_fragment_cached_false_with_cache_store_and_cache_except_and_cache_only
434434
end
435435

436436
def test_fragment_fetch_with_virtual_attributes
437-
@author = Author.new(name: 'Joao M. D. Moura')
438-
@role = Role.new(name: 'Great Author', description: nil)
439-
@role.author = [@author]
440-
@role_serializer = RoleSerializer.new(@role)
441-
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@role_serializer)
442-
@role_hash = @role_serializer.fetch_attributes_fragment(adapter_instance)
437+
author = Author.new(name: 'Joao M. D. Moura')
438+
role = Role.new(name: 'Great Author', description: nil)
439+
role.author = [author]
440+
role_serializer = RoleSerializer.new(role)
441+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(role_serializer)
442+
expected_result = {
443+
id: role.id,
444+
description: role.description,
445+
slug: "#{role.name}-#{role.id}",
446+
name: role.name
447+
}
448+
cache_store.clear
449+
450+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
451+
assert_equal(role_hash, expected_result)
452+
453+
role.attributes[:id] = 'this has been updated'
454+
role.name = 'this was cached'
443455

456+
role_hash = role_serializer.fetch_attributes_fragment(adapter_instance)
457+
assert_equal(expected_result.merge(id: role.id), role_hash)
458+
end
459+
460+
def test_fragment_fetch_with_except
461+
adapter_instance = ActiveModelSerializers::Adapter.configured_adapter.new(@bio_serializer)
444462
expected_result = {
445-
id: @role.id,
446-
description: @role.description,
447-
slug: "#{@role.name}-#{@role.id}",
448-
name: @role.name
463+
id: @bio.id,
464+
rating: nil,
465+
content: @bio.content
449466
}
467+
cache_store.clear
468+
469+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
470+
assert_equal(expected_result, bio_hash)
471+
472+
@bio.content = 'this has been updated'
473+
@bio.rating = 'this was cached'
450474

451-
assert_equal(@role_hash, expected_result)
475+
bio_hash = @bio_serializer.fetch_attributes_fragment(adapter_instance)
476+
assert_equal(expected_result.merge(content: @bio.content), bio_hash)
452477
end
453478

454479
def test_fragment_fetch_with_namespaced_object

test/fixtures/poro.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,10 +136,11 @@ def custom_options
136136
end
137137

138138
RoleSerializer = Class.new(ActiveModel::Serializer) do
139-
cache only: [:name], skip_digest: true
140-
attributes :id, :name, :description, :slug
139+
cache only: [:name, :slug], skip_digest: true
140+
attributes :id, :name, :description
141+
attribute :friendly_id, key: :slug
141142

142-
def slug
143+
def friendly_id
143144
"#{object.name}-#{object.id}"
144145
end
145146

@@ -153,10 +154,10 @@ def slug
153154
end
154155

155156
LocationSerializer = Class.new(ActiveModel::Serializer) do
156-
cache only: [:place], skip_digest: true
157+
cache only: [:address], skip_digest: true
157158
attributes :id, :lat, :lng
158159

159-
belongs_to :place
160+
belongs_to :place, key: :address
160161

161162
def place
162163
'Nowhere'

0 commit comments

Comments
 (0)