-
Notifications
You must be signed in to change notification settings - Fork 368
Expand file tree
/
Copy pathvcap_serialization.rb
More file actions
141 lines (126 loc) · 4.9 KB
/
vcap_serialization.rb
File metadata and controls
141 lines (126 loc) · 4.9 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
module Sequel::Plugins::VcapSerialization
# This plugin implements serialization and deserialization of
# Sequel::Models to/from hashes and json.
module InstanceMethods
# Return a hash of the model instance containing only the parameters
# specified by export_attributes.
#
# @option opts [Array<String>] :only Only export an attribute if it is both
# included in export_attributes and in the :only option.
#
# @return [Hash] The hash representation of the instance only containing
# the attributes specified by export_attributes and the optional :only
# parameter.
def to_hash(opts={})
hash = {}
redact_vals = opts[:redact]
attrs = opts[:attrs] || export_attrs
attrs.each do |k|
next unless opts[:only].nil? || opts[:only].include?(k)
value = send(k)
hash[k.to_s] = if value.respond_to?(:nil_object?) && value.nil_object?
nil
elsif !redact_vals.nil? && redact_vals.include?(k.to_s)
{ redacted_message: VCAP::CloudController::Presenters::Censorship::PRIVATE_DATA_HIDDEN }
else
value
end
end
hash
end
# Returns an array of attribute names that will be used when calling to_hash
def export_attrs
self.class.export_attrs || []
end
delegate :export_attrs_from_methods, to: :class
# Update the model instance from the supplied json string. Only update
# attributes specified by import_attributes.
#
# @param [String] Json encoded representation of the updated attributes.
#
# @option opts [Array<String>] :only Only import an attribute if it is both
# included in import_attributes and in the :only option.
def update_from_json(json, opts={})
parsed = Oj.load(json)
update_from_hash(parsed, opts)
end
# Update the model instance from the supplied hash. Only update
# attributes specified by import_attributes.
#
# @param [Hash] Hash of the updated attributes.
#
# @option opts [Array<String>] :only Only import an attribute if it is both
# included in import_attributes and in the :only option.
def update_from_hash(hash, opts={})
update_opts = self.class.update_or_create_options(hash, opts)
# Cannot use update(update_opts) because it does not
# update updated_at timestamp when no changes are being made.
# Arguably this should avoid updating updated_at if nothing changed.
set(update_opts)
save
end
end
module ClassMethods
# Create a new model instance from the supplied json string. Only include
# attributes specified by import_attributes.
#
# @param [String] Json encoded representation attributes.
#
# @option opts [Array<String>] :only Only include an attribute if it is
# both included in import_attributes and in the :only option.
#
# @return [Sequel::Model] The created model.
def create_from_json(json, opts={})
hash = Oj.load(json)
create_from_hash(hash, opts)
end
# Create and save a new model instance from the supplied json string.
# Only include attributes specified by import_attributes.
#
# @param [Hash] Hash of the attributes.
#
# @option opts [Array<String>] :only Only include an attribute if it is
# both included in import_attributes and in the :only option.
#
# @return [Sequel::Model] The created model.
def create_from_hash(hash, opts={})
create_opts = update_or_create_options(hash, opts)
create { |instance| instance.set(create_opts) }
end
# Set the default order during a to_json on the model class.
#
# @param [Array<Symbol>] List of attributes to include when serializing to
# json or a hash.
def export_attributes(*attributes)
self.export_attrs = attributes.freeze
end
# after serializing an object to a hash based on export_attributes and
# transient_attributes, swap in different values from methods on the object
def export_attributes_from_methods(hash)
self.export_attrs_from_methods = hash.freeze
end
# @param [Array<Symbol>] List of attributes to include when importing
# from json or a hash.
def import_attributes(*attributes)
self.import_attrs = attributes
end
# Not intended to be called by consumers of the API, but needed
# by instance of the class, so it can't be made private.
def update_or_create_options(hash, opts)
results = {}
attrs = import_attrs || []
attrs -= opts[:only] unless opts[:only].nil?
attrs.each do |attr|
key = nil
if hash.key?(attr)
key = attr
elsif hash.key?(attr.to_s)
key = attr.to_s
end
results[attr] = hash[key] unless key.nil?
end
results
end
attr_accessor :export_attrs, :import_attrs, :export_attrs_from_methods
end
end