-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathresource.rb
100 lines (85 loc) · 2.94 KB
/
resource.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require 'jsonapi/serializable/resource/dsl'
require 'jsonapi/serializable/link'
require 'jsonapi/serializable/relationship'
require 'jsonapi/serializable/resource/conditional_fields'
require 'jsonapi/serializable/resource/key_format'
module JSONAPI
module Serializable
class Resource
extend DSL
# Default the value of id.
id { @object.public_send(:id).to_s }
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def initialize(exposures = {})
@_exposures = exposures
@_exposures.each { |k, v| instance_variable_set("@#{k}", v) }
@_id = instance_eval(&self.class.id_block).to_s
@_type = if (b = self.class.type_block)
instance_eval(&b).to_sym
else
self.class.type_val || :unknown
end
@_relationships = self.class.relationship_blocks
.each_with_object({}) do |(k, v), h|
opts = self.class.relationship_options[k] || {}
opts = opts.merge(_resource: self)
h[k] = Relationship.new(@_exposures, opts, &v)
end
@_meta = if (b = self.class.meta_block)
instance_eval(&b)
else
self.class.meta_val
end
freeze
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
def as_jsonapi(fields: nil, include: [])
attrs = requested_attributes(fields).each_with_object({}) do |(k, v), h|
h[k] = instance_eval(&v)
end
rels = requested_relationships(fields)
.each_with_object({}) do |(k, v), h|
h[k] = v.as_jsonapi(include.include?(k))
end
links = link_blocks.each_with_object({}) do |(k, v), h|
h[k] = Link.as_jsonapi(@_exposures, &v)
end
{}.tap do |hash|
hash[:id] = @_id
hash[:type] = @_type
hash[:attributes] = attrs if attrs.any?
hash[:relationships] = rels if rels.any?
hash[:links] = links if links.any?
hash[:meta] = @_meta unless @_meta.nil?
end
end
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
def jsonapi_type
@_type
end
def jsonapi_id
@_id
end
def jsonapi_related(include)
@_relationships
.select { |k, _| include.include?(k) }
.each_with_object({}) { |(k, v), h| h[k] = v.related_resources }
end
private
# @api private
def requested_attributes(fields)
self.class.attribute_blocks
.select { |k, _| fields.nil? || fields.include?(k) }
end
# @api private
def requested_relationships(fields)
@_relationships.select { |k, _| fields.nil? || fields.include?(k) }
end
# @api private
def link_blocks
self.class.link_blocks
end
end
end
end