fast_serializer 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/HISTORY.md +11 -0
- data/README.md +31 -10
- data/VERSION +1 -1
- data/fast_serializer.gemspec +1 -0
- data/lib/fast_serializer.rb +16 -7
- data/lib/fast_serializer/array_serializer.rb +12 -12
- data/lib/fast_serializer/cache.rb +2 -2
- data/lib/fast_serializer/cache/active_support_cache.rb +4 -3
- data/lib/fast_serializer/serialization_context.rb +7 -7
- data/lib/fast_serializer/serialized_field.rb +6 -6
- data/lib/fast_serializer/serializer.rb +48 -41
- data/spec/array_serializer_spec.rb +7 -7
- data/spec/cache/active_support_cache_spec.rb +24 -0
- data/spec/fast_serializer_spec.rb +17 -5
- data/spec/serialization_context_spec.rb +4 -4
- data/spec/serialized_field_spec.rb +14 -14
- data/spec/serializer_spec.rb +32 -26
- data/spec/spec_helper.rb +3 -1
- data/spec/support/test_models.rb +6 -6
- metadata +20 -4
- data/HISTORY.txt +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9aa9a0f0945690089e7b2811fc8a7a2bd7d5d391a44d6ffd5da46fde8cde178a
|
4
|
+
data.tar.gz: 5c7767c57d03ec466b8b0b8a241ecaaf1190b04115db5bbe63a04884e302320e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b385a08ca0c432e8f8660e19f95ad0f33b43372084dcd9910a10410f3f7cd168158e1138bfae101a76a216e210b50dfdea7a8207864182ab96ef65f099cef53
|
7
|
+
data.tar.gz: 3b39610d1a17bece32360aac268b5fd508e0fe46bb2fd2b29fa22f6e422e93fa2c8ae7b11bdd926f848b30e8c40f68d508e6ffe57c04eeea8cbbeb77e06fcceb
|
data/HISTORY.md
ADDED
data/README.md
CHANGED
@@ -7,7 +7,7 @@ For these examples we'll assume we have a simple Person class.
|
|
7
7
|
```ruby
|
8
8
|
class Person
|
9
9
|
attr_accessor :id, :first_name, :last_name, :parents, :children
|
10
|
-
|
10
|
+
|
11
11
|
def intitialize(attributes = {})
|
12
12
|
@id = attributes[:id]
|
13
13
|
@first_name = attributes[:first_name]
|
@@ -16,7 +16,7 @@ class Person
|
|
16
16
|
@parent = attributes[:parents]
|
17
17
|
@children = attributes[:children] || {}
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def ==(other)
|
21
21
|
other.instance_of?(self.class) && other.id == id
|
22
22
|
end
|
@@ -31,7 +31,7 @@ ruby```
|
|
31
31
|
class PersonSerializer
|
32
32
|
include FastSerializer::Serializer
|
33
33
|
serialize :id, :name
|
34
|
-
|
34
|
+
|
35
35
|
def name
|
36
36
|
"#{object.first_name} #{object.last_name}"
|
37
37
|
end
|
@@ -47,7 +47,7 @@ class PersonSerializer
|
|
47
47
|
include FastSerializer::Serializer
|
48
48
|
serialize :id, as: :person_id
|
49
49
|
serialize :name, :delegate => false
|
50
|
-
|
50
|
+
|
51
51
|
def name
|
52
52
|
"#{object.first_name} #{object.last_name}"
|
53
53
|
end
|
@@ -65,7 +65,7 @@ class PersonSerializer
|
|
65
65
|
serialize :name, :delegate => false
|
66
66
|
serialize :parent, serializer: PersonSerializer
|
67
67
|
serialize :children, serializer: PersonSerializer, enumerable: true
|
68
|
-
|
68
|
+
|
69
69
|
def name
|
70
70
|
"#{object.first_name} #{object.last_name}"
|
71
71
|
end
|
@@ -81,6 +81,8 @@ PersonSerializer.new(person).as_json # => {
|
|
81
81
|
# }
|
82
82
|
```
|
83
83
|
|
84
|
+
### Optional and excluding fields
|
85
|
+
|
84
86
|
Serializer can have optional fields. You can also specify fields to exclude.
|
85
87
|
|
86
88
|
```ruby
|
@@ -89,7 +91,7 @@ class PersonSerializer
|
|
89
91
|
serialize :id
|
90
92
|
serialize :name, :delegate => false
|
91
93
|
serialize :gender, optional: true
|
92
|
-
|
94
|
+
|
93
95
|
def name
|
94
96
|
"#{object.first_name} #{object.last_name}"
|
95
97
|
end
|
@@ -100,6 +102,8 @@ PersonSerializer.new(person, :include => [:gender]).as_json # => {:id => 1, :nam
|
|
100
102
|
PersonSerializer.new(person, :exclude => [:id]).as_json # => {:name => "John Doe"}
|
101
103
|
```
|
102
104
|
|
105
|
+
### Serializer options
|
106
|
+
|
103
107
|
You can specify custom options that control how the object is serialized.
|
104
108
|
|
105
109
|
```ruby
|
@@ -107,7 +111,7 @@ class PersonSerializer
|
|
107
111
|
include FastSerializer::Serializer
|
108
112
|
serialize :id
|
109
113
|
serialize :name, :delegate => false
|
110
|
-
|
114
|
+
|
111
115
|
def name
|
112
116
|
if option(:last_first)
|
113
117
|
"#{object.last_name}, #{object.first_name}"
|
@@ -118,9 +122,11 @@ class PersonSerializer
|
|
118
122
|
end
|
119
123
|
|
120
124
|
PersonSerializer.new(person).as_json # => {:id => 1, :name => "John Doe"}
|
121
|
-
PersonSerializer.new(person, :last_first).as_json # => {:id => 1, :name => "Doe, John"}
|
125
|
+
PersonSerializer.new(person, :last_first => true).as_json # => {:id => 1, :name => "Doe, John"}
|
122
126
|
```
|
123
127
|
|
128
|
+
### Caching
|
129
|
+
|
124
130
|
You can make serializers cacheable so that the serialized value can be stored and fetched from a cache.
|
125
131
|
|
126
132
|
```ruby
|
@@ -128,9 +134,9 @@ class PersonSerializer
|
|
128
134
|
include FastSerializer::Serializer
|
129
135
|
serialize :id
|
130
136
|
serialize :name, :delegate => false
|
131
|
-
|
137
|
+
|
132
138
|
cacheable true, ttl: 60
|
133
|
-
|
139
|
+
|
134
140
|
def name
|
135
141
|
if option(:last_first)
|
136
142
|
"#{object.last_name}, #{object.first_name}"
|
@@ -143,6 +149,21 @@ end
|
|
143
149
|
FastSerializer.cache = MyCache.new # Must be an implementation of FastSerializer::Cache
|
144
150
|
```
|
145
151
|
|
152
|
+
For Rails application, you can run this in an initializer to tell `FastSerializer` to use `Rails.cache`
|
153
|
+
|
154
|
+
```ruby
|
155
|
+
FastSerializer.cache = :rails
|
156
|
+
```
|
157
|
+
|
158
|
+
You can also pass a cache to a serializer using the `:cache` option.
|
159
|
+
|
160
|
+
### Collections
|
161
|
+
|
162
|
+
If you have a collection of objects to serialize, you can use the `FastSerializer::ArraySerializer` to serialize an enumeration of objects.
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
```
|
166
|
+
|
146
167
|
## Performance
|
147
168
|
|
148
169
|
Your mileage may vary. In many cases the performance of the serialization code doesn't particularly matter and this gem performs just about as well as other solutions. However, if you do have high throughput API or can utilize the caching features or have heavily nested models in your JSON responses, then the performance increase may be noticeable.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/fast_serializer.gemspec
CHANGED
data/lib/fast_serializer.rb
CHANGED
@@ -9,25 +9,34 @@ module FastSerializer
|
|
9
9
|
require_relative 'fast_serializer/serialized_field'
|
10
10
|
require_relative 'fast_serializer/serializer'
|
11
11
|
require_relative 'fast_serializer/array_serializer'
|
12
|
-
|
12
|
+
|
13
13
|
class << self
|
14
|
+
@cache = nil
|
15
|
+
|
14
16
|
# Get the global cache implementation used for storing cacheable serializers.
|
15
17
|
def cache
|
16
|
-
@cache
|
18
|
+
@cache
|
17
19
|
end
|
18
|
-
|
20
|
+
|
19
21
|
# Set the global cache implementation used for storing cacheable serializers.
|
20
|
-
# The cache implementation should implement the +fetch+ method as defined in
|
22
|
+
# The cache implementation should implement the +fetch+ method as defined in
|
21
23
|
# FastSerializer::Cache. By default no cache is set so caching won't do anything.
|
22
24
|
#
|
23
25
|
# In a Rails app, you can initialize the cache by simply passing in the value :rails
|
24
|
-
# to use the default Rails.cache.
|
26
|
+
# to use the default Rails.cache. You can also directly pass in an ActiveSupportCache::Store.
|
25
27
|
def cache=(cache)
|
26
|
-
|
28
|
+
if cache == :rails
|
29
|
+
cache = Cache::ActiveSupportCache.new(Rails.cache)
|
30
|
+
elsif defined?(ActiveSupport::Cache::Store) && cache.is_a?(ActiveSupport::Cache::Store)
|
31
|
+
cache = Cache::ActiveSupportCache.new(cache)
|
32
|
+
end
|
33
|
+
if cache && !cache.is_a?(FastSerializer::Cache)
|
34
|
+
raise ArgumentError.new("The cache must be a FastSerializer::Cache or ActiveSupport::Cache::Store")
|
35
|
+
end
|
27
36
|
@cache = cache
|
28
37
|
end
|
29
38
|
end
|
30
|
-
|
39
|
+
|
31
40
|
# Exception raised when there is a circular reference serializing a model dependent on itself.
|
32
41
|
class CircularReferenceError < StandardError
|
33
42
|
def initialize(model)
|
@@ -4,13 +4,13 @@ module FastSerializer
|
|
4
4
|
# for caching duplicate serializers.
|
5
5
|
class ArraySerializer
|
6
6
|
include Serializer
|
7
|
-
|
7
|
+
|
8
8
|
serialize :array
|
9
|
-
|
9
|
+
|
10
10
|
def initialize(object, options = nil)
|
11
11
|
super(Array(object), options)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def cache_key
|
15
15
|
if option(:serializer)
|
16
16
|
array.collect(&:cache_key)
|
@@ -18,7 +18,7 @@ module FastSerializer
|
|
18
18
|
super
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def cacheable?
|
23
23
|
if option(:cacheable) || self.class.cacheable?
|
24
24
|
true
|
@@ -28,7 +28,7 @@ module FastSerializer
|
|
28
28
|
super
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def cache_ttl
|
33
33
|
if option(:cache_ttl)
|
34
34
|
true
|
@@ -38,7 +38,7 @@ module FastSerializer
|
|
38
38
|
super
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def cache
|
43
43
|
if option(:cache)
|
44
44
|
true
|
@@ -48,7 +48,7 @@ module FastSerializer
|
|
48
48
|
super
|
49
49
|
end
|
50
50
|
end
|
51
|
-
|
51
|
+
|
52
52
|
def as_json(*args)
|
53
53
|
if array.nil?
|
54
54
|
nil
|
@@ -58,13 +58,13 @@ module FastSerializer
|
|
58
58
|
super[:array]
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
undef :to_hash
|
63
63
|
undef :to_h
|
64
64
|
alias :to_a :as_json
|
65
|
-
|
65
|
+
|
66
66
|
protected
|
67
|
-
|
67
|
+
|
68
68
|
def load_from_cache
|
69
69
|
if cache
|
70
70
|
values = cache.fetch_all(array, cache_ttl){|serializer| serializer.as_json}
|
@@ -73,9 +73,9 @@ module FastSerializer
|
|
73
73
|
load_hash
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
private
|
78
|
-
|
78
|
+
|
79
79
|
def array
|
80
80
|
unless defined?(@_array)
|
81
81
|
serializer = option(:serializer)
|
@@ -5,11 +5,11 @@ module FastSerializer
|
|
5
5
|
def fetch(serializer, ttl, &block)
|
6
6
|
raise NotImplementedError
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
# Fetch multiple serializers from the cache. The default behavior is just
|
10
10
|
# to call +fetch+ with each serializer. Implementations may optimize this
|
11
11
|
# if the cache can return multiple values at once.
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# The block to this method will be yielded to with each uncached serializer.
|
14
14
|
def fetch_all(serializers, ttl)
|
15
15
|
serializers.collect do |serializer|
|
@@ -7,9 +7,10 @@ module FastSerializer
|
|
7
7
|
@cache = cache
|
8
8
|
end
|
9
9
|
|
10
|
-
def fetch(serializer, ttl
|
11
|
-
|
12
|
-
|
10
|
+
def fetch(serializer, ttl)
|
11
|
+
@cache.fetch(serializer.cache_key, :expires_in => ttl) do
|
12
|
+
yield(serializer)
|
13
|
+
end
|
13
14
|
end
|
14
15
|
|
15
16
|
def fetch_all(serializers, ttl)
|
@@ -19,18 +19,18 @@ module FastSerializer
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Return the current context or nil if none is in use.
|
24
24
|
def current
|
25
25
|
Thread.current[:fast_serializer_context]
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def initialize
|
30
30
|
@cache = nil
|
31
31
|
@references = nil
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
# Returns a serializer from the context cache if a duplicate has already
|
35
35
|
# been created. Otherwise creates the serializer and adds it to the
|
36
36
|
# cache.
|
@@ -40,17 +40,17 @@ module FastSerializer
|
|
40
40
|
if @cache
|
41
41
|
serializer = @cache[key]
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
unless serializer
|
45
45
|
serializer = serializer_class.allocate
|
46
46
|
serializer.send(:initialize, object, options)
|
47
47
|
@cache ||= {}
|
48
48
|
@cache[key] = serializer
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
serializer
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
# Maintain reference stack to avoid circular references.
|
55
55
|
def with_reference(object)
|
56
56
|
if @references
|
@@ -58,7 +58,7 @@ module FastSerializer
|
|
58
58
|
else
|
59
59
|
@references = []
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
begin
|
63
63
|
@references.push(object)
|
64
64
|
yield
|
@@ -2,7 +2,7 @@ module FastSerializer
|
|
2
2
|
# Data structure used internally for maintaining a field to be serialized.
|
3
3
|
class SerializedField
|
4
4
|
attr_reader :name
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(name, optional: false, serializer: nil, serializer_options: nil, enumerable: false)
|
7
7
|
@name = name
|
8
8
|
@optional = !!optional
|
@@ -12,11 +12,11 @@ module FastSerializer
|
|
12
12
|
@enumerable = enumerable
|
13
13
|
end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
def optional?
|
17
17
|
@optional
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# Wrap a value in the serializer if one has been set. Otherwise just returns the raw value.
|
21
21
|
def serialize(value)
|
22
22
|
if value && @serializer
|
@@ -36,9 +36,9 @@ module FastSerializer
|
|
36
36
|
serialize_value(value)
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
private
|
41
|
-
|
41
|
+
|
42
42
|
# Convert the value to primitive data types: string, number, boolean, symbol, time, date, array, hash.
|
43
43
|
def serialize_value(value)
|
44
44
|
if value.is_a?(String) || value.is_a?(Numeric) || value == nil || value == true || value == false || value.is_a?(Time) || value.is_a?(Date) || value.is_a?(Symbol)
|
@@ -73,6 +73,6 @@ module FastSerializer
|
|
73
73
|
value
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
end
|
78
78
|
end
|
@@ -55,17 +55,17 @@ module FastSerializer
|
|
55
55
|
#
|
56
56
|
# Serializing a nil object will result in nil rather than an empty hash.
|
57
57
|
module Serializer
|
58
|
-
|
58
|
+
|
59
59
|
def self.included(base)
|
60
60
|
base.extend(ClassMethods)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
# Return the wrapped object that is being serialized.
|
64
64
|
attr_reader :object
|
65
|
-
|
65
|
+
|
66
66
|
# Return the options hash (if any) that specified optional details about how to serialize the object.
|
67
67
|
attr_reader :options
|
68
|
-
|
68
|
+
|
69
69
|
module ClassMethods
|
70
70
|
# Define one or more fields to include in the serialized object. Field values will be gotten
|
71
71
|
# by calling the method of the same name on class including this module.
|
@@ -100,23 +100,23 @@ module FastSerializer
|
|
100
100
|
if as && fields.size > 1
|
101
101
|
raise ArgumentError.new("Cannot specify :as argument with multiple fields to serialize")
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
fields.each do |field|
|
105
105
|
name = as
|
106
106
|
if name.nil? && field.to_s.end_with?("?".freeze)
|
107
107
|
name = field.to_s.chomp("?".freeze)
|
108
108
|
end
|
109
|
-
|
109
|
+
|
110
110
|
field = field.to_sym
|
111
111
|
attribute = (name || field).to_sym
|
112
112
|
add_field(attribute, optional: optional, serializer: serializer, serializer_options: serializer_options, enumerable: enumerable)
|
113
|
-
|
113
|
+
|
114
114
|
if delegate && !method_defined?(attribute)
|
115
115
|
define_delegate(attribute, field)
|
116
116
|
end
|
117
117
|
end
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
# Remove a field from being serialized. This can be useful in subclasses if they need to remove a
|
121
121
|
# field defined by the parent class.
|
122
122
|
def remove(*fields)
|
@@ -127,11 +127,11 @@ module FastSerializer
|
|
127
127
|
end
|
128
128
|
@serializable_fields = field_list.freeze
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
# Specify the cacheability of the serializer.
|
132
132
|
#
|
133
133
|
# You can specify the cacheable state (defaults to true) of the class. Subclasses will inherit the
|
134
|
-
# cacheable state of their parent class, so if you have non-cacheable serializer subclassing a
|
134
|
+
# cacheable state of their parent class, so if you have non-cacheable serializer subclassing a
|
135
135
|
# cacheable parent class, you can call <tt>cacheable false</tt> to override the parent behavior.
|
136
136
|
#
|
137
137
|
# You can also specify the cache time to live (ttl) in seconds and the cache implementation to use.
|
@@ -141,7 +141,7 @@ module FastSerializer
|
|
141
141
|
self.cache_ttl = ttl if ttl
|
142
142
|
self.cache = cache if cache
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
# Return true if the serializer class is cacheable.
|
146
146
|
def cacheable?
|
147
147
|
unless defined?(@cacheable)
|
@@ -149,7 +149,7 @@ module FastSerializer
|
|
149
149
|
end
|
150
150
|
!!@cacheable
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
# Return the time to live in seconds for a cacheable serializer.
|
154
154
|
def cache_ttl
|
155
155
|
if defined?(@cache_ttl)
|
@@ -160,12 +160,12 @@ module FastSerializer
|
|
160
160
|
nil
|
161
161
|
end
|
162
162
|
end
|
163
|
-
|
163
|
+
|
164
164
|
# Set the time to live on a cacheable serializer.
|
165
165
|
def cache_ttl=(value)
|
166
166
|
@cache_ttl = value
|
167
167
|
end
|
168
|
-
|
168
|
+
|
169
169
|
# Get the cache implemtation used to store cacheable serializers.
|
170
170
|
def cache
|
171
171
|
if defined?(@cache)
|
@@ -176,12 +176,15 @@ module FastSerializer
|
|
176
176
|
FastSerializer.cache
|
177
177
|
end
|
178
178
|
end
|
179
|
-
|
179
|
+
|
180
180
|
# Set the cache implementation used to store cacheable serializers.
|
181
181
|
def cache=(cache)
|
182
|
+
if defined?(ActiveSupport::Cache::Store) && cache.is_a?(ActiveSupport::Cache::Store)
|
183
|
+
cache = Cache::ActiveSupportCache.new(cache)
|
184
|
+
end
|
182
185
|
@cache = cache
|
183
186
|
end
|
184
|
-
|
187
|
+
|
185
188
|
# :nodoc:
|
186
189
|
def new(object, options = nil)
|
187
190
|
context = SerializationContext.current
|
@@ -192,7 +195,7 @@ module FastSerializer
|
|
192
195
|
super
|
193
196
|
end
|
194
197
|
end
|
195
|
-
|
198
|
+
|
196
199
|
# Return a list of the SerializedFields defined for the class.
|
197
200
|
def serializable_fields
|
198
201
|
unless defined?(@serializable_fields) && @serializable_fields
|
@@ -202,14 +205,14 @@ module FastSerializer
|
|
202
205
|
end
|
203
206
|
@serializable_fields
|
204
207
|
end
|
205
|
-
|
208
|
+
|
206
209
|
private
|
207
|
-
|
210
|
+
|
208
211
|
# Add a field to be serialized.
|
209
212
|
def add_field(name, optional:, serializer:, serializer_options:, enumerable:)
|
210
213
|
name = name.to_sym
|
211
214
|
field = SerializedField.new(name, optional: optional, serializer: serializer, serializer_options: serializer_options, enumerable: enumerable)
|
212
|
-
|
215
|
+
|
213
216
|
# Add the field to the frozen list of fields.
|
214
217
|
field_list = []
|
215
218
|
added = false
|
@@ -223,13 +226,13 @@ module FastSerializer
|
|
223
226
|
field_list << field unless added
|
224
227
|
@serializable_fields = field_list.freeze
|
225
228
|
end
|
226
|
-
|
229
|
+
|
227
230
|
# Define a delegate method name +attribute+ that invokes the +field+ method on the wrapped object.
|
228
231
|
def define_delegate(attribute, field)
|
229
|
-
define_method(attribute){ object.send(field) }
|
232
|
+
define_method(attribute){ object.send(field) }
|
230
233
|
end
|
231
234
|
end
|
232
|
-
|
235
|
+
|
233
236
|
# Create a new serializer for the specified object.
|
234
237
|
#
|
235
238
|
# Options can be passed in to control how the object is serialized. Options supported by all Serializers:
|
@@ -242,9 +245,13 @@ module FastSerializer
|
|
242
245
|
def initialize(object, options = nil)
|
243
246
|
@object = object
|
244
247
|
@options = options
|
248
|
+
@cache = options[:cache] if options
|
249
|
+
if @cache && defined?(ActiveSupport::Cache::Store) && cache.is_a?(ActiveSupport::Cache::Store)
|
250
|
+
@cache = Cache::ActiveSupportCache.new(@cache)
|
251
|
+
end
|
245
252
|
@_serialized = nil
|
246
253
|
end
|
247
|
-
|
254
|
+
|
248
255
|
# Serialize the wrapped object into a format suitable for passing to a JSON parser.
|
249
256
|
def as_json(*args)
|
250
257
|
return nil unless object
|
@@ -253,54 +260,54 @@ module FastSerializer
|
|
253
260
|
end
|
254
261
|
@_serialized
|
255
262
|
end
|
256
|
-
|
263
|
+
|
257
264
|
alias :to_hash :as_json
|
258
265
|
alias :to_h :as_json
|
259
|
-
|
266
|
+
|
260
267
|
# Convert the wrapped object to JSON format.
|
261
|
-
def to_json(options =
|
268
|
+
def to_json(options = {})
|
262
269
|
if defined?(MultiJson)
|
263
|
-
MultiJson.dump(as_json)
|
270
|
+
MultiJson.dump(as_json, options)
|
264
271
|
else
|
265
272
|
JSON.dump(as_json)
|
266
273
|
end
|
267
274
|
end
|
268
|
-
|
275
|
+
|
269
276
|
# Fetch the specified option from the options hash.
|
270
277
|
def option(name)
|
271
278
|
@options[name] if @options
|
272
279
|
end
|
273
|
-
|
280
|
+
|
274
281
|
# Return true if this serializer is cacheable.
|
275
282
|
def cacheable?
|
276
283
|
option(:cacheable) || self.class.cacheable?
|
277
284
|
end
|
278
|
-
|
285
|
+
|
279
286
|
# Return the cache implementation where this serializer can be stored.
|
280
287
|
def cache
|
281
|
-
|
288
|
+
@cache || self.class.cache
|
282
289
|
end
|
283
|
-
|
290
|
+
|
284
291
|
# Return the time to live in seconds this serializer can be cached for.
|
285
292
|
def cache_ttl
|
286
293
|
option(:cache_ttl) || self.class.cache_ttl
|
287
294
|
end
|
288
|
-
|
295
|
+
|
289
296
|
# Returns a array of the elements that make this serializer unique. The
|
290
297
|
# key is an array made up of the serializer class name, wrapped object, and
|
291
298
|
# serialization options hash.
|
292
299
|
def cache_key
|
293
300
|
[self.class.name, object, options]
|
294
301
|
end
|
295
|
-
|
302
|
+
|
296
303
|
# :nodoc:
|
297
304
|
def ==(other)
|
298
305
|
other.instance_of?(self.class) && @object == other.object && @options == other.options
|
299
306
|
end
|
300
307
|
alias_method :eql?, :==
|
301
|
-
|
308
|
+
|
302
309
|
protected
|
303
|
-
|
310
|
+
|
304
311
|
# Load the hash that will represent the wrapped object as a serialized object.
|
305
312
|
def load_hash
|
306
313
|
hash = {}
|
@@ -319,7 +326,7 @@ module FastSerializer
|
|
319
326
|
end
|
320
327
|
hash
|
321
328
|
end
|
322
|
-
|
329
|
+
|
323
330
|
# Load the hash that will represent the wrapped object as a serialized object from a cache.
|
324
331
|
def load_from_cache
|
325
332
|
if cache
|
@@ -330,9 +337,9 @@ module FastSerializer
|
|
330
337
|
load_hash
|
331
338
|
end
|
332
339
|
end
|
333
|
-
|
340
|
+
|
334
341
|
private
|
335
|
-
|
342
|
+
|
336
343
|
# Return a list of optional fields to be included in the output from the :include option.
|
337
344
|
def included_optional_fields
|
338
345
|
included_fields = option(:include)
|
@@ -342,7 +349,7 @@ module FastSerializer
|
|
342
349
|
nil
|
343
350
|
end
|
344
351
|
end
|
345
|
-
|
352
|
+
|
346
353
|
# Return a list of fields to be excluded from the output from the :exclude option.
|
347
354
|
def excluded_regular_fields
|
348
355
|
excluded_fields = option(:exclude)
|
@@ -1,19 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FastSerializer::ArraySerializer do
|
4
|
-
|
4
|
+
|
5
5
|
it "should serialize an array of regular objects" do
|
6
6
|
array = [1, 2, 3]
|
7
7
|
serializer = FastSerializer::ArraySerializer.new(array)
|
8
8
|
expect(serializer.as_json).to eq array
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
it "should serialize any Enumerable" do
|
12
12
|
hash = {:a => 1, :b => 2}
|
13
13
|
serializer = FastSerializer::ArraySerializer.new(hash)
|
14
14
|
expect(serializer.as_json).to eq hash.to_a
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "should serializer an array of objects using a specific serializer" do
|
18
18
|
model_1 = SimpleModel.new(:id => 1, :name => "foo")
|
19
19
|
model_2 = SimpleModel.new(:id => 2, :name => "bar")
|
@@ -23,7 +23,7 @@ describe FastSerializer::ArraySerializer do
|
|
23
23
|
{"id" => 2, "name" => "bar", "validated" => false}
|
24
24
|
]
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
it "should serializer an array of objects using a specific serializer with options" do
|
28
28
|
model_1 = SimpleModel.new(:id => 1, :name => "foo")
|
29
29
|
model_2 = SimpleModel.new(:id => 2, :name => "bar")
|
@@ -33,20 +33,20 @@ describe FastSerializer::ArraySerializer do
|
|
33
33
|
{"id" => 2, "name" => "bar", "validated" => false, "description" => nil}
|
34
34
|
]
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
it "should not respond to_hash methods" do
|
38
38
|
array = [1, 2, 3]
|
39
39
|
serializer = FastSerializer::ArraySerializer.new(array)
|
40
40
|
expect(serializer.respond_to?(:to_hash)).to eq false
|
41
41
|
expect(serializer.respond_to?(:to_h)).to eq false
|
42
42
|
end
|
43
|
-
|
43
|
+
|
44
44
|
it "should respond to to_a" do
|
45
45
|
array = [1, 2, 3]
|
46
46
|
serializer = FastSerializer::ArraySerializer.new(array)
|
47
47
|
expect(serializer.to_a).to eq array
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
it "should pull cacheable serializers from a cache" do
|
51
51
|
model_1 = SimpleModel.new(:id => 1, :name => "foo")
|
52
52
|
model_2 = SimpleModel.new(:id => 2, :name => "bar")
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe FastSerializer::Cache::ActiveSupportCache do
|
4
|
+
|
5
|
+
it "should fetch from an ActiveSupport cache store" do
|
6
|
+
cache_store = ActiveSupport::Cache::MemoryStore.new
|
7
|
+
cache = FastSerializer::Cache::ActiveSupportCache.new(cache_store)
|
8
|
+
serializer = SimpleSerializer.new(SimpleModel.new(:id => 1))
|
9
|
+
|
10
|
+
expect(cache.fetch(serializer, 60){|s| s.as_json} ).to eq serializer.as_json
|
11
|
+
expect(cache.fetch(serializer, 60){ raise "boom" }).to eq serializer.as_json
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should fetch multiple from an ActiveSupport cache store" do
|
15
|
+
cache_store = ActiveSupport::Cache::MemoryStore.new
|
16
|
+
cache = FastSerializer::Cache::ActiveSupportCache.new(cache_store)
|
17
|
+
s1 = SimpleSerializer.new(SimpleModel.new(:id => 1))
|
18
|
+
s2 = SimpleSerializer.new(SimpleModel.new(:id => 2))
|
19
|
+
|
20
|
+
expect(cache.fetch_all([s1, s2], 60){|s| s.as_json} ).to eq [s1.as_json, s2.as_json]
|
21
|
+
expect(cache.fetch_all([s1, s2], 60){ raise "boom" }).to eq [s1.as_json, s2.as_json]
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -1,18 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FastSerializer do
|
4
|
-
|
4
|
+
|
5
5
|
it "should be able to set and get a global cache" do
|
6
6
|
expect(FastSerializer.cache).to eq nil
|
7
7
|
begin
|
8
|
-
|
9
|
-
|
8
|
+
cache = TestCache.new
|
9
|
+
FastSerializer.cache = cache
|
10
|
+
expect(FastSerializer.cache).to eq cache
|
10
11
|
ensure
|
11
12
|
FastSerializer.cache = nil
|
12
13
|
end
|
13
14
|
expect(FastSerializer.cache).to eq nil
|
14
15
|
end
|
15
|
-
|
16
|
+
|
16
17
|
it "should set the cache to Rails.cache with the value :rails" do
|
17
18
|
begin
|
18
19
|
rails = double(:cache => :rails_cache)
|
@@ -24,5 +25,16 @@ describe FastSerializer do
|
|
24
25
|
FastSerializer.cache = nil
|
25
26
|
end
|
26
27
|
end
|
27
|
-
|
28
|
+
|
29
|
+
it "should set the cache with an ActiveSupport cache" do
|
30
|
+
begin
|
31
|
+
cache_store = ActiveSupport::Cache::MemoryStore.new
|
32
|
+
FastSerializer.cache = cache_store
|
33
|
+
expect(FastSerializer.cache).to be_a FastSerializer::Cache::ActiveSupportCache
|
34
|
+
expect(FastSerializer.cache.cache).to eq cache_store
|
35
|
+
ensure
|
36
|
+
FastSerializer.cache = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
28
40
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FastSerializer::SerializationContext do
|
4
|
-
|
4
|
+
|
5
5
|
it "should get a single context only within a block" do
|
6
6
|
expect(FastSerializer::SerializationContext.current).to eq nil
|
7
7
|
FastSerializer::SerializationContext.use do
|
@@ -14,11 +14,11 @@ describe FastSerializer::SerializationContext do
|
|
14
14
|
end
|
15
15
|
expect(FastSerializer::SerializationContext.current).to eq nil
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "should create serializers and reload them from cache with the same object and options" do
|
19
19
|
context = FastSerializer::SerializationContext.new
|
20
20
|
object = SimpleModel.new(:id => 1, :name => "foo")
|
21
|
-
|
21
|
+
|
22
22
|
serializer = context.load(SimpleSerializer, object, :count => 1)
|
23
23
|
expect(serializer).to be_a SimpleSerializer
|
24
24
|
expect(serializer.object).to eq object
|
@@ -28,5 +28,5 @@ describe FastSerializer::SerializationContext do
|
|
28
28
|
expect(context.load(SimpleSerializer, SimpleModel.new(:id => 2, :name => "bar"), :count => 1).object_id).to_not eq serializer.object_id
|
29
29
|
expect(context.load(SimpleSerializer, object, :count => 2).object_id).to_not eq serializer.object_id
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
@@ -1,66 +1,66 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FastSerializer::SerializedField do
|
4
|
-
|
4
|
+
|
5
5
|
let(:field){ FastSerializer::SerializedField.new(:test) }
|
6
6
|
let(:model){ SimpleModel.new(:id => 1, :name => "foo") }
|
7
|
-
|
7
|
+
|
8
8
|
it "should integers" do
|
9
9
|
expect(field.serialize(1)).to eq 1
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
it "should serialize floats" do
|
13
13
|
expect(field.serialize(1.5)).to eq 1.5
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
it "should serialize strings" do
|
17
17
|
expect(field.serialize("foo")).to eq "foo"
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "should serialize symbols" do
|
21
21
|
expect(field.serialize(:foo)).to eq :foo
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
it "should serialize nil" do
|
25
25
|
expect(field.serialize(nil)).to eq nil
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
it "should serialize booleans" do
|
29
29
|
expect(field.serialize(true)).to eq true
|
30
30
|
expect(field.serialize(false)).to eq false
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
it "should serialize times" do
|
34
34
|
time = Time.now
|
35
35
|
expect(field.serialize(time)).to eq time
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "should serialize dates" do
|
39
39
|
date = Date.today
|
40
40
|
expect(field.serialize(date)).to eq date
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
it "should serialize a field using a specified serializer" do
|
44
44
|
field = FastSerializer::SerializedField.new(:test, serializer: SimpleSerializer)
|
45
45
|
expect(field.serialize(model)).to eq({:id => 1, :name => "foo", :validated => false})
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
it "should serialize an enumerable field using a specified serializer" do
|
49
49
|
field = FastSerializer::SerializedField.new(:test, serializer: SimpleSerializer, enumerable: true)
|
50
50
|
expect(field.serialize(model)).to eq([{:id => 1, :name => "foo", :validated => false}])
|
51
51
|
end
|
52
|
-
|
52
|
+
|
53
53
|
it "should serialize a field value by calling as_json on the field" do
|
54
54
|
expect(field.serialize(model)).to eq({:id => 1, :name => "foo", :description => nil, :number => nil})
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
it "should serialize a hash of objects" do
|
58
58
|
expect(field.serialize(:name => "Test", :object => model)).to eq({
|
59
59
|
:name => "Test",
|
60
60
|
:object => {:id => 1, :name => "foo", :description => nil, :number => nil}
|
61
61
|
})
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
it "should serialize an array of objects" do
|
65
65
|
expect(field.serialize([model, model])).to eq([
|
66
66
|
{:id => 1, :name => "foo", :description => nil, :number => nil},
|
data/spec/serializer_spec.rb
CHANGED
@@ -1,93 +1,93 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FastSerializer::Serializer do
|
4
|
-
|
4
|
+
|
5
5
|
let(:model){ SimpleModel.new(:id => 1, :name => "foo", :description => "foobar") }
|
6
|
-
|
6
|
+
|
7
7
|
it "should serialize object to JSON compatible format" do
|
8
8
|
serializer = SimpleSerializer.new(model)
|
9
9
|
expect(serializer.as_json).to eq({:id => 1, :name => "foo", :validated => false})
|
10
10
|
expect(serializer.to_hash).to eq({:id => 1, :name => "foo", :validated => false})
|
11
11
|
expect(serializer.to_h).to eq({:id => 1, :name => "foo", :validated => false})
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
it "should serialize nil as nil" do
|
15
15
|
expect(SimpleSerializer.new(nil).as_json).to eq nil
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
it "should include optional fields only if included in the options" do
|
19
19
|
expect(SimpleSerializer.new(model).as_json).to eq({:id => 1, :name => "foo", :validated => false})
|
20
20
|
expect(SimpleSerializer.new(model, :include => :nothing).as_json).to eq({:id => 1, :name => "foo", :validated => false})
|
21
21
|
expect(SimpleSerializer.new(model, :include => :description).as_json).to eq({:id => 1, :name => "foo", :validated => false, :description => "foobar"})
|
22
22
|
expect(SimpleSerializer.new(model, :include => ["description"]).as_json).to eq({:id => 1, :name => "foo", :validated => false, :description => "foobar"})
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
it "should exclude specified fields" do
|
26
26
|
expect(SimpleSerializer.new(model, :exclude => :name).as_json).to eq({:id => 1, :validated => false})
|
27
27
|
expect(SimpleSerializer.new(model, :exclude => ["id", "validated"]).as_json).to eq({:name => "foo"})
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
it "should allow aliasing fields" do
|
31
31
|
number_model = SimpleModel.new(:number => 50.5)
|
32
32
|
expect(SimpleSerializer.new(number_model, :include => :amount).as_json).to eq({:id => nil, :name => nil, :validated => false, :amount => 50.5})
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
it "should pull cached serializers from a cache" do
|
36
36
|
serializer = SimpleSerializer.new(model)
|
37
37
|
cached_serializer = CachedSerializer.new(model)
|
38
|
-
|
38
|
+
|
39
39
|
expect(serializer.cacheable?).to eq false
|
40
40
|
expect(cached_serializer.cacheable?).to eq true
|
41
|
-
|
41
|
+
|
42
42
|
expect(serializer.cache_ttl).to eq nil
|
43
43
|
expect(cached_serializer.cache_ttl).to eq 2
|
44
|
-
|
44
|
+
|
45
45
|
expect(cached_serializer.as_json).to eq serializer.as_json
|
46
46
|
expect(cached_serializer.as_json.object_id).to eq cached_serializer.as_json.object_id
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
it "should allow setting cache and ttl on parent serializers" do
|
50
50
|
class SubCacheSerializer1 < CachedSerializer
|
51
51
|
self.cache_ttl = 5
|
52
52
|
self.cache = :mock
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
class SubCacheSerializer2 < CachedSerializer
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
expect(SubCacheSerializer1.cacheable?).to eq true
|
59
59
|
expect(SubCacheSerializer2.cacheable?).to eq true
|
60
|
-
|
60
|
+
|
61
61
|
expect(SubCacheSerializer1.cache).to eq :mock
|
62
62
|
expect(SubCacheSerializer2.cache).to eq CachedSerializer.cache
|
63
|
-
|
63
|
+
|
64
64
|
expect(SubCacheSerializer1.cache_ttl).to eq 5
|
65
65
|
expect(SubCacheSerializer2.cache_ttl).to eq 2
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
it "should allow setting cache and ttl on instances" do
|
69
69
|
serializer = SimpleSerializer.new(model, :cacheable => true, :cache => :mock, :cache_ttl => 10)
|
70
70
|
expect(serializer.cacheable?).to eq true
|
71
71
|
expect(serializer.cache).to eq :mock
|
72
72
|
expect(serializer.cache_ttl).to eq 10
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
it "should get the cache from the global setting by default" do
|
76
76
|
class SubCacheSerializerGlobalInheritTest
|
77
77
|
include FastSerializer::Serializer
|
78
78
|
self.cacheable
|
79
79
|
end
|
80
|
-
|
81
|
-
expect(SubCacheSerializerGlobalInheritTest.cache).to eq nil
|
80
|
+
|
81
|
+
expect(SubCacheSerializerGlobalInheritTest.cache).to eq nil
|
82
82
|
allow(FastSerializer).to receive_messages(:cache => :mock)
|
83
83
|
expect(SubCacheSerializerGlobalInheritTest.cache).to eq :mock
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
it "should not break on cached serializers if no cache is set" do
|
87
87
|
serializer = CachedSerializer.new(model, :cache => nil)
|
88
88
|
expect(serializer.as_json).to eq({:id => 1, :name => "foo", :validated => false})
|
89
89
|
end
|
90
|
-
|
90
|
+
|
91
91
|
it "should serialize complex objects" do
|
92
92
|
other_model = SimpleModel.new(:id => 3, :name => "other")
|
93
93
|
complex = SimpleModel.new(:id => 2, :name => :complex, :parent => model, :associations => [model, other_model])
|
@@ -101,7 +101,7 @@ describe FastSerializer::Serializer do
|
|
101
101
|
:parent => {:id => 1, :name => "foo", :validated => false}
|
102
102
|
})
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
it "should return identical serialized values for serializers on the same object and options inside the same context" do
|
106
106
|
other_model = SimpleModel.new(:id => 3, :name => "other")
|
107
107
|
complex = SimpleModel.new(:id => 2, :name => "complex", :associations => [model, other_model, model])
|
@@ -110,7 +110,7 @@ describe FastSerializer::Serializer do
|
|
110
110
|
expect(json[:associations][0].object_id).to_not eq json[:associations][1].object_id
|
111
111
|
expect(json[:associations][0].object_id).to eq json[:associations][2].object_id
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
it "should dump the object to JSON" do
|
115
115
|
complex = SimpleModel.new(:id => 2, :name => "complex", :parent => model, :associations => [model])
|
116
116
|
serializer = ComplexSerializer.new(complex)
|
@@ -125,18 +125,24 @@ describe FastSerializer::Serializer do
|
|
125
125
|
"parent" => {"id" => 1, "name" => "foo", "validated" => false}
|
126
126
|
})
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
|
+
it "should allow passing options for JSON dumping" do
|
130
|
+
complex = SimpleModel.new(:id => 2, :name => "complex", :parent => model, :associations => [model])
|
131
|
+
serializer = ComplexSerializer.new(complex)
|
132
|
+
expect(serializer.to_json(:pretty => true)).to be_a(String)
|
133
|
+
end
|
134
|
+
|
129
135
|
it "should expose options from the options hash by name" do
|
130
136
|
serializer = CachedSerializer.new(model, :foo => "bar")
|
131
137
|
expect(serializer.option(:foo)).to eq "bar"
|
132
138
|
expect(serializer.option(:other)).to eq nil
|
133
139
|
end
|
134
|
-
|
140
|
+
|
135
141
|
it "should return nil value for options if none are set" do
|
136
142
|
serializer = CachedSerializer.new(model, nil)
|
137
143
|
expect(serializer.option(:foo)).to eq nil
|
138
144
|
end
|
139
|
-
|
145
|
+
|
140
146
|
it "should not get into infinite loops" do
|
141
147
|
model = SimpleModel.new(:id => 1)
|
142
148
|
model.parent = model
|
data/spec/spec_helper.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'rspec'
|
2
|
+
require 'active_support/cache'
|
3
|
+
require 'active_support/cache/memory_store'
|
2
4
|
require_relative "../lib/fast_serializer"
|
3
5
|
require_relative "support/test_models"
|
4
6
|
|
@@ -11,6 +13,6 @@ RSpec.configure do |config|
|
|
11
13
|
# the seed, which is printed after each run.
|
12
14
|
# --seed 1234
|
13
15
|
config.order = 'random'
|
14
|
-
|
16
|
+
|
15
17
|
config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }
|
16
18
|
end
|
data/spec/support/test_models.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class SimpleModel
|
2
2
|
attr_reader :id, :name, :description, :associations, :number
|
3
3
|
attr_accessor :parent
|
4
|
-
|
4
|
+
|
5
5
|
def initialize(attributes = {})
|
6
6
|
@id = attributes[:id]
|
7
7
|
@name = attributes[:name]
|
@@ -11,11 +11,11 @@ class SimpleModel
|
|
11
11
|
@parent = attributes[:parent]
|
12
12
|
@number = attributes[:number]
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def validated?
|
16
16
|
!!@validated
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def as_json(*args)
|
20
20
|
{:id => @id, :name => @name, :description => @description, :number => @number}
|
21
21
|
end
|
@@ -25,7 +25,7 @@ class TestCache < FastSerializer::Cache
|
|
25
25
|
def initialize
|
26
26
|
@cache = {}
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def fetch(serializer, ttl)
|
30
30
|
val = @cache[serializer.cache_key]
|
31
31
|
unless val
|
@@ -38,7 +38,7 @@ end
|
|
38
38
|
|
39
39
|
class SimpleSerializer
|
40
40
|
include FastSerializer::Serializer
|
41
|
-
|
41
|
+
|
42
42
|
serialize :id, :name, :validated?
|
43
43
|
serialize :description, optional: true
|
44
44
|
serialize :number, as: :amount, optional: true
|
@@ -52,7 +52,7 @@ class ComplexSerializer < SimpleSerializer
|
|
52
52
|
serialize :serial_number, delegate: false
|
53
53
|
serialize :associations, delegate: true, serializer: CachedSerializer, enumerable: true
|
54
54
|
serialize :parent, delegate: true, serializer: SimpleSerializer
|
55
|
-
|
55
|
+
|
56
56
|
def serial_number
|
57
57
|
option(:serial_number)
|
58
58
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fast_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- We Heart It
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-08-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -53,6 +53,20 @@ dependencies:
|
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
55
|
version: '3.0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: active_support
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '4.0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '4.0'
|
56
70
|
description: Super fast object serialization for API's combining a simple DSL with
|
57
71
|
many optimizations under the hood.
|
58
72
|
email:
|
@@ -63,7 +77,7 @@ extensions: []
|
|
63
77
|
extra_rdoc_files: []
|
64
78
|
files:
|
65
79
|
- ".gitignore"
|
66
|
-
- HISTORY.
|
80
|
+
- HISTORY.md
|
67
81
|
- MIT_LICENSE
|
68
82
|
- README.md
|
69
83
|
- Rakefile
|
@@ -77,6 +91,7 @@ files:
|
|
77
91
|
- lib/fast_serializer/serialized_field.rb
|
78
92
|
- lib/fast_serializer/serializer.rb
|
79
93
|
- spec/array_serializer_spec.rb
|
94
|
+
- spec/cache/active_support_cache_spec.rb
|
80
95
|
- spec/fast_serializer_spec.rb
|
81
96
|
- spec/serialization_context_spec.rb
|
82
97
|
- spec/serialized_field_spec.rb
|
@@ -103,12 +118,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
118
|
version: '0'
|
104
119
|
requirements: []
|
105
120
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.6
|
121
|
+
rubygems_version: 2.7.6
|
107
122
|
signing_key:
|
108
123
|
specification_version: 4
|
109
124
|
summary: Super fast object serialization for API's.
|
110
125
|
test_files:
|
111
126
|
- spec/array_serializer_spec.rb
|
127
|
+
- spec/cache/active_support_cache_spec.rb
|
112
128
|
- spec/fast_serializer_spec.rb
|
113
129
|
- spec/serialization_context_spec.rb
|
114
130
|
- spec/serialized_field_spec.rb
|