fast_jsonapi 1.3 → 1.4
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/README.md +23 -5
- data/lib/fast_jsonapi/object_serializer.rb +26 -8
- data/lib/fast_jsonapi/relationship.rb +17 -9
- data/lib/fast_jsonapi/serialization_core.rb +20 -7
- data/lib/fast_jsonapi/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 759626d247d6cc39f75b0080a9c09493e9fcc93b
|
4
|
+
data.tar.gz: 57dc5e3a5fd9014d3a7f276f3c9d353bb9f328f4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 390b6f6df1591307f33afd1996d563ead9f04294a6e9670a82263388c9ae408b94d5321bce265c2ed3336f714999496525fd2a3866e8d710c27791bbfd42193b
|
7
|
+
data.tar.gz: 69e7198dea45b109c630555328ea8847af80a2ea4938fc743f862f4f8eb1e8513af090ee537c55ac79b202c1724483ea5b9574567f81fe0ef6d83efb55fb8c7d
|
data/README.md
CHANGED
@@ -221,7 +221,7 @@ end
|
|
221
221
|
```
|
222
222
|
|
223
223
|
### Links Per Object
|
224
|
-
Links are defined in FastJsonapi using the `link` method. By default, link are read directly from the model property of the same name.In this example, `public_url` is expected to be a property of the object being serialized.
|
224
|
+
Links are defined in FastJsonapi using the `link` method. By default, link are read directly from the model property of the same name. In this example, `public_url` is expected to be a property of the object being serialized.
|
225
225
|
|
226
226
|
You can configure the method to use on the object for example a link with key `self` will get set to the value returned by a method called `url` on the movie object.
|
227
227
|
|
@@ -245,6 +245,23 @@ class MovieSerializer
|
|
245
245
|
end
|
246
246
|
```
|
247
247
|
|
248
|
+
### Meta Per Resource
|
249
|
+
|
250
|
+
For every resource in the collection, you can include a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.
|
251
|
+
|
252
|
+
|
253
|
+
```ruby
|
254
|
+
class MovieSerializer
|
255
|
+
include FastJsonapi::ObjectSerializer
|
256
|
+
|
257
|
+
meta do |movie|
|
258
|
+
{
|
259
|
+
years_since_release: Date.current.year - movie.year
|
260
|
+
}
|
261
|
+
end
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
248
265
|
### Compound Document
|
249
266
|
|
250
267
|
Support for top-level and nested included associations through ` options[:include] `.
|
@@ -351,15 +368,15 @@ class MovieSerializer
|
|
351
368
|
include FastJsonapi::ObjectSerializer
|
352
369
|
|
353
370
|
attributes :name, :year
|
354
|
-
attribute :release_year, if: Proc.new
|
371
|
+
attribute :release_year, if: Proc.new { |record|
|
355
372
|
# Release year will only be serialized if it's greater than 1990
|
356
373
|
record.release_year > 1990
|
357
|
-
|
374
|
+
}
|
358
375
|
|
359
|
-
attribute :director, if: Proc.new
|
376
|
+
attribute :director, if: Proc.new { |record, params|
|
360
377
|
# The director will be serialized only if the :admin key of params is true
|
361
378
|
params && params[:admin] == true
|
362
|
-
|
379
|
+
}
|
363
380
|
end
|
364
381
|
|
365
382
|
# ...
|
@@ -409,6 +426,7 @@ serializer.serializable_hash
|
|
409
426
|
Option | Purpose | Example
|
410
427
|
------------ | ------------- | -------------
|
411
428
|
set_type | Type name of Object | ```set_type :movie ```
|
429
|
+
key | Key of Object | ```belongs_to :owner, key: :user ```
|
412
430
|
set_id | ID of Object | ```set_id :owner_id ```
|
413
431
|
cache_options | Hash to enable caching and set cache length | ```cache_options enabled: true, cache_length: 12.hours, race_condition_ttl: 10.seconds```
|
414
432
|
id_method_name | Set custom method name to get ID of an object | ```has_many :locations, id_method_name: :place_ids ```
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'active_support/
|
3
|
+
require 'active_support/json'
|
4
4
|
require 'active_support/concern'
|
5
5
|
require 'active_support/inflector'
|
6
6
|
require 'fast_jsonapi/attribute'
|
@@ -65,7 +65,7 @@ module FastJsonapi
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def serialized_json
|
68
|
-
|
68
|
+
ActiveSupport::JSON.encode(serializable_hash)
|
69
69
|
end
|
70
70
|
|
71
71
|
private
|
@@ -120,6 +120,7 @@ module FastJsonapi
|
|
120
120
|
subclass.data_links = data_links
|
121
121
|
subclass.cached = cached
|
122
122
|
subclass.set_type(subclass.reflected_record_type) if subclass.reflected_record_type
|
123
|
+
subclass.meta_to_serialize = meta_to_serialize
|
123
124
|
end
|
124
125
|
|
125
126
|
def reflected_record_type
|
@@ -194,7 +195,7 @@ module FastJsonapi
|
|
194
195
|
self.relationships_to_serialize = {} if relationships_to_serialize.nil?
|
195
196
|
self.cachable_relationships_to_serialize = {} if cachable_relationships_to_serialize.nil?
|
196
197
|
self.uncachable_relationships_to_serialize = {} if uncachable_relationships_to_serialize.nil?
|
197
|
-
|
198
|
+
|
198
199
|
if !relationship.cached
|
199
200
|
self.uncachable_relationships_to_serialize[relationship.name] = relationship
|
200
201
|
else
|
@@ -218,6 +219,10 @@ module FastJsonapi
|
|
218
219
|
add_relationship(relationship)
|
219
220
|
end
|
220
221
|
|
222
|
+
def meta(&block)
|
223
|
+
self.meta_to_serialize = block
|
224
|
+
end
|
225
|
+
|
221
226
|
def create_relationship(base_key, relationship_type, options, block)
|
222
227
|
name = base_key.to_sym
|
223
228
|
if relationship_type == :has_many
|
@@ -232,7 +237,11 @@ module FastJsonapi
|
|
232
237
|
Relationship.new(
|
233
238
|
key: options[:key] || run_key_transform(base_key),
|
234
239
|
name: name,
|
235
|
-
id_method_name:
|
240
|
+
id_method_name: compute_id_method_name(
|
241
|
+
options[:id_method_name],
|
242
|
+
"#{base_serialization_key}#{id_postfix}".to_sym,
|
243
|
+
block
|
244
|
+
),
|
236
245
|
record_type: options[:record_type] || run_key_transform(base_key_sym),
|
237
246
|
object_method_name: options[:object_method_name] || name,
|
238
247
|
object_block: block,
|
@@ -240,10 +249,19 @@ module FastJsonapi
|
|
240
249
|
relationship_type: relationship_type,
|
241
250
|
cached: options[:cached],
|
242
251
|
polymorphic: fetch_polymorphic_option(options),
|
243
|
-
conditional_proc: options[:if]
|
252
|
+
conditional_proc: options[:if],
|
253
|
+
transform_method: @transform_method
|
244
254
|
)
|
245
255
|
end
|
246
256
|
|
257
|
+
def compute_id_method_name(custom_id_method_name, id_method_name_from_relationship, block)
|
258
|
+
if block.present?
|
259
|
+
custom_id_method_name || :id
|
260
|
+
else
|
261
|
+
custom_id_method_name || id_method_name_from_relationship
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
247
265
|
def compute_serializer_name(serializer_key)
|
248
266
|
return serializer_key unless serializer_key.is_a? Symbol
|
249
267
|
namespace = self.name.gsub(/()?\w+Serializer$/, '')
|
@@ -275,10 +293,10 @@ module FastJsonapi
|
|
275
293
|
includes.detect do |include_item|
|
276
294
|
klass = self
|
277
295
|
parse_include_item(include_item).each do |parsed_include|
|
278
|
-
|
296
|
+
relationships_to_serialize = klass.relationships_to_serialize || {}
|
297
|
+
relationship_to_include = relationships_to_serialize[parsed_include]
|
279
298
|
raise ArgumentError, "#{parsed_include} is not specified as a relationship on #{klass.name}" unless relationship_to_include
|
280
|
-
|
281
|
-
klass = relationship_to_include.serializer.to_s.constantize
|
299
|
+
klass = relationship_to_include.serializer.to_s.constantize unless relationship_to_include.polymorphic.is_a?(Hash)
|
282
300
|
end
|
283
301
|
end
|
284
302
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module FastJsonapi
|
2
2
|
class Relationship
|
3
|
-
attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc
|
3
|
+
attr_reader :key, :name, :id_method_name, :record_type, :object_method_name, :object_block, :serializer, :relationship_type, :cached, :polymorphic, :conditional_proc, :transform_method
|
4
4
|
|
5
5
|
def initialize(
|
6
6
|
key:,
|
@@ -13,7 +13,8 @@ module FastJsonapi
|
|
13
13
|
relationship_type:,
|
14
14
|
cached: false,
|
15
15
|
polymorphic:,
|
16
|
-
conditional_proc
|
16
|
+
conditional_proc:,
|
17
|
+
transform_method:
|
17
18
|
)
|
18
19
|
@key = key
|
19
20
|
@name = name
|
@@ -26,6 +27,7 @@ module FastJsonapi
|
|
26
27
|
@cached = cached
|
27
28
|
@polymorphic = polymorphic
|
28
29
|
@conditional_proc = conditional_proc
|
30
|
+
@transform_method = transform_method
|
29
31
|
end
|
30
32
|
|
31
33
|
def serialize(record, serialization_params, output_hash)
|
@@ -68,7 +70,7 @@ module FastJsonapi
|
|
68
70
|
|
69
71
|
def id_hash_from_record(record, record_types)
|
70
72
|
# memoize the record type within the record_types dictionary, then assigning to record_type:
|
71
|
-
associated_record_type = record_types[record.class] ||= record.class.name.underscore
|
73
|
+
associated_record_type = record_types[record.class] ||= run_key_transform(record.class.name.demodulize.underscore)
|
72
74
|
id_hash(record.id, associated_record_type)
|
73
75
|
end
|
74
76
|
|
@@ -86,14 +88,20 @@ module FastJsonapi
|
|
86
88
|
end
|
87
89
|
|
88
90
|
def fetch_id(record, params)
|
89
|
-
|
91
|
+
if object_block.present?
|
90
92
|
object = object_block.call(record, params)
|
91
|
-
|
92
|
-
return object.
|
93
|
-
return object.try(:id)
|
93
|
+
return object.map { |item| item.public_send(id_method_name) } if object.respond_to? :map
|
94
|
+
return object.try(id_method_name)
|
94
95
|
end
|
95
|
-
|
96
96
|
record.public_send(id_method_name)
|
97
97
|
end
|
98
|
+
|
99
|
+
def run_key_transform(input)
|
100
|
+
if self.transform_method.present?
|
101
|
+
input.to_s.send(*self.transform_method).to_sym
|
102
|
+
else
|
103
|
+
input.to_sym
|
104
|
+
end
|
105
|
+
end
|
98
106
|
end
|
99
|
-
end
|
107
|
+
end
|
@@ -21,7 +21,8 @@ module FastJsonapi
|
|
21
21
|
:cache_length,
|
22
22
|
:race_condition_ttl,
|
23
23
|
:cached,
|
24
|
-
:data_links
|
24
|
+
:data_links,
|
25
|
+
:meta_to_serialize
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
@@ -57,6 +58,10 @@ module FastJsonapi
|
|
57
58
|
end
|
58
59
|
end
|
59
60
|
|
61
|
+
def meta_hash(record, params = {})
|
62
|
+
meta_to_serialize.call(record, params)
|
63
|
+
end
|
64
|
+
|
60
65
|
def record_hash(record, fieldset, params = {})
|
61
66
|
if cached
|
62
67
|
record_hash = Rails.cache.fetch(record.cache_key, expires_in: cache_length, race_condition_ttl: race_condition_ttl) do
|
@@ -67,13 +72,15 @@ module FastJsonapi
|
|
67
72
|
temp_hash[:links] = links_hash(record, params) if data_links.present?
|
68
73
|
temp_hash
|
69
74
|
end
|
70
|
-
record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, params)) if uncachable_relationships_to_serialize.present?
|
75
|
+
record_hash[:relationships] = record_hash[:relationships].merge(relationships_hash(record, uncachable_relationships_to_serialize, fieldset, params)) if uncachable_relationships_to_serialize.present?
|
76
|
+
record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present?
|
71
77
|
record_hash
|
72
78
|
else
|
73
79
|
record_hash = id_hash(id_from_record(record), record_type, true)
|
74
80
|
record_hash[:attributes] = attributes_hash(record, fieldset, params) if attributes_to_serialize.present?
|
75
81
|
record_hash[:relationships] = relationships_hash(record, nil, fieldset, params) if relationships_to_serialize.present?
|
76
82
|
record_hash[:links] = links_hash(record, params) if data_links.present?
|
83
|
+
record_hash[:meta] = meta_hash(record, params) if meta_to_serialize.present?
|
77
84
|
record_hash
|
78
85
|
end
|
79
86
|
end
|
@@ -112,9 +119,10 @@ module FastJsonapi
|
|
112
119
|
next unless relationships_to_serialize && relationships_to_serialize[item]
|
113
120
|
relationship_item = relationships_to_serialize[item]
|
114
121
|
next unless relationship_item.include_relationship?(record, params)
|
115
|
-
|
116
|
-
|
117
|
-
|
122
|
+
unless relationship_item.polymorphic.is_a?(Hash)
|
123
|
+
record_type = relationship_item.record_type
|
124
|
+
serializer = relationship_item.serializer.to_s.constantize
|
125
|
+
end
|
118
126
|
relationship_type = relationship_item.relationship_type
|
119
127
|
|
120
128
|
included_objects = relationship_item.fetch_associated_object(record, params)
|
@@ -122,12 +130,17 @@ module FastJsonapi
|
|
122
130
|
included_objects = [included_objects] unless relationship_type == :has_many
|
123
131
|
|
124
132
|
included_objects.each do |inc_obj|
|
133
|
+
if relationship_item.polymorphic.is_a?(Hash)
|
134
|
+
record_type = inc_obj.class.name.demodulize.underscore
|
135
|
+
serializer = self.compute_serializer_name(inc_obj.class.name.demodulize.to_sym).to_s.constantize
|
136
|
+
end
|
137
|
+
|
125
138
|
if remaining_items(items)
|
126
|
-
serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects, fieldsets)
|
139
|
+
serializer_records = serializer.get_included_records(inc_obj, remaining_items(items), known_included_objects, fieldsets, params)
|
127
140
|
included_records.concat(serializer_records) unless serializer_records.empty?
|
128
141
|
end
|
129
142
|
|
130
|
-
code = "#{record_type}_#{inc_obj
|
143
|
+
code = "#{record_type}_#{serializer.id_from_record(inc_obj)}"
|
131
144
|
next if known_included_objects.key?(code)
|
132
145
|
|
133
146
|
known_included_objects[code] = inc_obj
|
data/lib/fast_jsonapi/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_jsonapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '1.
|
4
|
+
version: '1.4'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shishir Kakaraddi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-09-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|