fast_serializer 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 612f91c858c466052eb82d76560f4acb6bf55f416a2da7d104b0d3c97d40cddb
4
- data.tar.gz: 7a515141fcad3e9ed626abd98bb67ce049b00a520a8a1d7e87e99245cfd397e1
3
+ metadata.gz: a7cb104ff4ece3439d2fcd7b6276866359a9ead6a511765fbef327d4bd33e168
4
+ data.tar.gz: dfff11c222e5cf0dc6352097fc3de8603f437fdc92636030c0aef4576b697445
5
5
  SHA512:
6
- metadata.gz: b4dc18b54f002e692ed98c5977f14df1233bd10f71093222098c127412e0455a714f5182d1c8666a8d30915020849edaf61596305724d1437b5e96baf21b7eb4
7
- data.tar.gz: 4636276312fcb0654cec728e93f35f717dc58c23960588716713c8589a52c5bc59e0b4b143a441199740c26d40d51a665f58ce6ccef599f87f31fd03efb94857
6
+ metadata.gz: 891c9cfde95aa08e4e2f73646f3cde78c4a1730673e9e74d518356dda869ff4848d1c9fc0d81bbcda936147faedd5e32775870a006e99679d34918f554252c70
7
+ data.tar.gz: 68814c806dd3b6a3b9e519b8ed5bf8c948ca2d12cb143a64a25c71aaac93690a66f5d85ea2ff71953d1bade1479f619b29c400ebab8137de947fb55053928d21
data/CHANGELOG.md ADDED
@@ -0,0 +1,46 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## 1.1.3
8
+
9
+ ### Added
10
+ - Optimize object shapes for the Ruby interpreter by declaring instance variables in constructors.
11
+
12
+ ## 1.1.2
13
+
14
+ ### Added
15
+ - Sanity check for unsupported options
16
+
17
+ ### Fixed
18
+ - Handle converting ActiveSupport::TimeWithZone to a Time so it can be better dumped to non-JSON formats.
19
+
20
+ ## 1.1.1
21
+
22
+ ### Added
23
+ - Add `array` class method to serializers.
24
+
25
+ ## 1.1.0
26
+
27
+ ### Added
28
+ - Add helper method for scope option.
29
+ - Pass serialization options to child serializers.
30
+ - Add `if` option to conditionally include fields.
31
+ - Better cache keys handling for more complex objects.
32
+
33
+ ## 1.0.2
34
+
35
+ ### Added
36
+ - Better integration with ActiveSupport caching.
37
+
38
+ ## 1.0.1
39
+
40
+ ### Fixed
41
+ - Compatibility with change to fetch_multi in ActiveSupport 4.2.
42
+
43
+ ## 1.0.0
44
+
45
+ ### Added
46
+ - Initial release
data/MIT_LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2016 We Heart It
1
+ Copyright (c) 2016 Brian Durand
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
- [![Build Status](https://travis-ci.org/weheartit/fast_serializer.svg?branch=master)](https://travis-ci.org/weheartit/fast_serializer)
2
- [![Maintainability](https://api.codeclimate.com/v1/badges/02fd32c734e667432df6/maintainability)](https://codeclimate.com/github/bdurand/fast_serializer/maintainability)
1
+ [![Continuous Integration](https://github.com/bdurand/fast_serializer/actions/workflows/continuous_integration.yml/badge.svg)](https://github.com/bdurand/fast_serializer/actions/workflows/continuous_integration.yml)
2
+ [![Regression Test](https://github.com/bdurand/fast_serializer/actions/workflows/regression_test.yml/badge.svg)](https://github.com/bdurand/fast_serializer/actions/workflows/regression_test.yml)
3
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
3
4
 
4
5
  This gem provides a highly optimized framework for serializing Ruby objects into hashes suitable for serialization to some other format (i.e. JSON). It provides many of the same features as other serialization frameworks like active_model_serializers, but it is designed to emphasize code efficiency over feature set and syntactic surgar.
5
6
 
@@ -232,7 +233,33 @@ You can also use the `array` helper class method on a serializer to do the same
232
233
  PersonSerializer.array([a, b, c, d])
233
234
  ```
234
235
 
235
-
236
236
  ## Performance
237
237
 
238
238
  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.
239
+ ## Installation
240
+
241
+ Add this line to your application's Gemfile:
242
+
243
+ ```ruby
244
+ gem 'fast_serializer'
245
+ ```
246
+
247
+ And then execute:
248
+ ```bash
249
+ $ bundle
250
+ ```
251
+
252
+ Or install it yourself as:
253
+ ```bash
254
+ $ gem install fast_serializer
255
+ ```
256
+
257
+ ## Contributing
258
+
259
+ Open a pull request on GitHub.
260
+
261
+ Please use the [standardrb](https://github.com/testdouble/standard) syntax and lint your code with `standardrb --fix` before submitting.
262
+
263
+ ## License
264
+
265
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.2
1
+ 1.1.3
@@ -1,24 +1,34 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
-
5
1
  Gem::Specification.new do |spec|
6
- spec.name = "fast_serializer"
7
- spec.version = File.read(File.expand_path("../VERSION", __FILE__)).chomp
8
- spec.authors = ["We Heart It", "Brian Durand"]
9
- spec.email = ["dev@weheartit.com", "bbdurand@gmail.com"]
10
- spec.description = %q{Super fast object serialization for API's combining a simple DSL with many optimizations under the hood.}
11
- spec.summary = %q{Super fast object serialization for API's.}
12
- spec.homepage = "https://github.com/weheartit/fast_serializer"
13
- spec.license = "MIT"
2
+ spec.name = "fast_serializer"
3
+ spec.version = File.read(File.expand_path("VERSION", __dir__)).strip
4
+ spec.authors = ["Brian Durand"]
5
+ spec.email = ["bbdurand@gmail.com"]
6
+
7
+ spec.summary = "Super fast object serialization for API's combining a simple DSL with many optimizations under the hood."
8
+ spec.homepage = "https://github.com/bdurand/fast_serializer"
9
+ spec.license = "MIT"
10
+
11
+ # Specify which files should be added to the gem when it is released.
12
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
13
+ ignore_files = %w[
14
+ .
15
+ Appraisals
16
+ Gemfile
17
+ Gemfile.lock
18
+ Rakefile
19
+ bin/
20
+ gemfiles/
21
+ spec/
22
+ ]
23
+ spec.files = Dir.chdir(__dir__) do
24
+ `git ls-files -z`.split("\x0").reject { |f| ignore_files.any? { |path| f.start_with?(path) } }
25
+ end
14
26
 
15
- spec.files = `git ls-files`.split($/)
16
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
27
  spec.require_paths = ["lib"]
19
28
 
20
- spec.add_development_dependency "bundler", "~>2.0"
21
- spec.add_development_dependency "rake"
22
- spec.add_development_dependency "rspec", "~>3.0"
23
- spec.add_development_dependency "activesupport", ">=4.0"
29
+ spec.required_ruby_version = ">= 2.5"
30
+
31
+ spec.add_dependency("redis")
32
+
33
+ spec.add_development_dependency "bundler"
24
34
  end
@@ -10,9 +10,11 @@ module FastSerializer
10
10
  serialize :array
11
11
 
12
12
  def initialize(object, options = nil)
13
+ @_array = nil
13
14
  super(Array(object), options)
14
15
  end
15
16
 
17
+ # @return [String]
16
18
  def cache_key
17
19
  if option(:serializer)
18
20
  array.collect(&:cache_key)
@@ -21,6 +23,7 @@ module FastSerializer
21
23
  end
22
24
  end
23
25
 
26
+ # @return [Boolean]
24
27
  def cacheable?
25
28
  if option(:cacheable) || self.class.cacheable?
26
29
  true
@@ -31,6 +34,7 @@ module FastSerializer
31
34
  end
32
35
  end
33
36
 
37
+ # @return [Numeric, Boolean]
34
38
  def cache_ttl
35
39
  if option(:cache_ttl)
36
40
  true
@@ -41,6 +45,7 @@ module FastSerializer
41
45
  end
42
46
  end
43
47
 
48
+ # @return [FastSerializer::Cache, Boolean]
44
49
  def cache
45
50
  if option(:cache)
46
51
  true
@@ -51,6 +56,7 @@ module FastSerializer
51
56
  end
52
57
  end
53
58
 
59
+ # @return [Hash]
54
60
  def as_json(*args)
55
61
  if array.nil?
56
62
  nil
@@ -63,14 +69,14 @@ module FastSerializer
63
69
 
64
70
  undef :to_hash
65
71
  undef :to_h
66
- alias :to_a :as_json
72
+ alias_method :to_a, :as_json
67
73
 
68
74
  protected
69
75
 
70
76
  def load_from_cache
71
77
  if cache
72
- values = cache.fetch_all(array, cache_ttl){|serializer| serializer.as_json}
73
- {:array => values}
78
+ values = cache.fetch_all(array, cache_ttl) { |serializer| serializer.as_json }
79
+ {array: values}
74
80
  else
75
81
  load_hash
76
82
  end
@@ -79,11 +85,11 @@ module FastSerializer
79
85
  private
80
86
 
81
87
  def array
82
- unless defined?(@_array)
88
+ if @_array.nil?
83
89
  serializer = option(:serializer)
84
90
  if serializer
85
91
  serializer_options = option(:serializer_options)
86
- @_array = object.collect{|obj| serializer.new(obj, serializer_options)}
92
+ @_array = object.collect { |obj| serializer.new(obj, serializer_options) }
87
93
  else
88
94
  @_array = object
89
95
  end
@@ -4,21 +4,21 @@ module FastSerializer
4
4
  # ActiveSupport compatible cache implementation.
5
5
  class Cache::ActiveSupportCache < Cache
6
6
  attr_reader :cache
7
-
7
+
8
8
  def initialize(cache)
9
9
  @cache = cache
10
10
  end
11
-
11
+
12
12
  def fetch(serializer, ttl)
13
- @cache.fetch(serializer.cache_key, :expires_in => ttl) do
13
+ @cache.fetch(serializer.cache_key, expires_in: ttl) do
14
14
  yield(serializer)
15
15
  end
16
16
  end
17
-
17
+
18
18
  def fetch_all(serializers, ttl)
19
- results = @cache.fetch_multi(*serializers){|serializer| yield(serializer)}
19
+ results = @cache.fetch_multi(*serializers) { |serializer| yield(serializer) }
20
20
  if results.is_a?(Hash)
21
- serializers.collect{|serializer| results[serializer]}
21
+ serializers.collect { |serializer| results[serializer] }
22
22
  else
23
23
  results
24
24
  end
@@ -4,6 +4,13 @@ module FastSerializer
4
4
  # Base class for cache implementations for storing cacheable serializers.
5
5
  # Implementations must implement the +fetch+ method.
6
6
  class Cache
7
+ # Fetch a serialized value from the cache. If the value is not cached, the
8
+ # block will be yielded to to generate the value.
9
+ #
10
+ # @param serializer [FastSerializer::Serializer] The serializer to fetch the value for.
11
+ # @param ttl [Numeric] The time to live for the cached value.
12
+ # @yieldparam serializer [FastSerializer::Serializer] The serializer to generate the value for.
13
+ # @return [Object] The serialized value.
7
14
  def fetch(serializer, ttl, &block)
8
15
  raise NotImplementedError
9
16
  end
@@ -13,6 +20,11 @@ module FastSerializer
13
20
  # if the cache can return multiple values at once.
14
21
  #
15
22
  # The block to this method will be yielded to with each uncached serializer.
23
+ #
24
+ # @param serializers [Array<FastSerializer::Serializer>] The serializers to fetch the values for.
25
+ # @param ttl [Numeric] The time to live for the cached values.
26
+ # @yieldparam serializer [FastSerializer::Serializer] A serializer to generate the value for.
27
+ # @return [Array<Object>] The serialized values.
16
28
  def fetch_all(serializers, ttl)
17
29
  serializers.collect do |serializer|
18
30
  fetch(serializer, ttl) do
@@ -9,6 +9,8 @@ module FastSerializer
9
9
  # Use a context or create one for use within a block. Any serializers
10
10
  # based on the same object with the same options within the block will be
11
11
  # re-used instead of creating duplicates.
12
+ #
13
+ # @return [Object] The return value of the block.
12
14
  def use
13
15
  if Thread.current[:fast_serializer_context]
14
16
  yield
@@ -23,6 +25,8 @@ module FastSerializer
23
25
  end
24
26
 
25
27
  # Return the current context or nil if none is in use.
28
+ #
29
+ # @return [FastSerializer::SerializationContext, nil]
26
30
  def current
27
31
  Thread.current[:fast_serializer_context]
28
32
  end
@@ -33,9 +37,14 @@ module FastSerializer
33
37
  @references = nil
34
38
  end
35
39
 
36
- # Returns a serializer from the context cache if a duplicate has already
40
+ # Returns a serializer from the context cache if one has already
37
41
  # been created. Otherwise creates the serializer and adds it to the
38
42
  # cache.
43
+ #
44
+ # @param serializer_class [Class] The serializer class to create.
45
+ # @param object [Object] The object to serialize.
46
+ # @param options [Hash] The options to pass to the serializer.
47
+ # @return [FastSerializer::Serializer] The serializer.
39
48
  def load(serializer_class, object, options = nil)
40
49
  key = [serializer_class, object, options]
41
50
  serializer = nil
@@ -46,7 +55,7 @@ module FastSerializer
46
55
  unless serializer
47
56
  serializer = serializer_class.allocate
48
57
  serializer.send(:initialize, object, options)
49
- @cache ||= {}
58
+ @cache = {}
50
59
  @cache[key] = serializer
51
60
  end
52
61
 
@@ -54,6 +63,10 @@ module FastSerializer
54
63
  end
55
64
 
56
65
  # Maintain reference stack to avoid circular references.
66
+ #
67
+ # @param object [Object] The object to check for circular references.
68
+ # @yield The block to execute.
69
+ # @return The return value of the block.
57
70
  def with_reference(object)
58
71
  if @references
59
72
  raise CircularReferenceError.new(object) if @references.include?(object)
@@ -5,8 +5,16 @@ module FastSerializer
5
5
  class SerializedField
6
6
  attr_reader :name, :condition
7
7
 
8
+ # Create a new serialized field.
9
+ #
10
+ # @param name [Symbol] the name of the field
11
+ # @param optional [Boolean] whether the field is optional
12
+ # @param serializer [Class] the serializer to use for the field
13
+ # @param serializer_options [Hash] the options to pass to the serializer
14
+ # @param enumerable [Boolean] whether the field is enumerable
15
+ # @param condition [Proc] a condition to determine whether the field should be serialized
8
16
  def initialize(name, optional: false, serializer: nil, serializer_options: nil, enumerable: false, condition: nil)
9
- @name = name
17
+ @name = name.to_sym
10
18
  @optional = !!optional
11
19
  @condition = condition
12
20
  if serializer
@@ -16,22 +24,27 @@ module FastSerializer
16
24
  end
17
25
  end
18
26
 
27
+ # @return [Boolean] true if the field is optional
19
28
  def optional?
20
29
  @optional
21
30
  end
22
31
 
23
32
  # Wrap a value in the serializer if one has been set. Otherwise just returns the raw value.
33
+ #
34
+ # @param value [Object] the value to serialize
35
+ # @param options [Hash] the options to pass to the serializer
36
+ # @return [Object] the serialized value
24
37
  def serialize(value, options = nil)
25
38
  if value && @serializer
26
39
  serializer = nil
27
- if @enumerable
28
- serializer = ArraySerializer.new(value, :serializer => @serializer, :serializer_options => serializer_options(options))
40
+ serializer = if @enumerable
41
+ ArraySerializer.new(value, serializer: @serializer, serializer_options: serializer_options(options))
29
42
  else
30
- serializer = @serializer.new(value, serializer_options(options))
43
+ @serializer.new(value, serializer_options(options))
31
44
  end
32
45
  context = SerializationContext.current
33
46
  if context
34
- context.with_reference(value){ serializer.as_json }
47
+ context.with_reference(value) { serializer.as_json }
35
48
  else
36
49
  serializer.as_json
37
50
  end
@@ -58,10 +71,10 @@ module FastSerializer
58
71
  retval = {}
59
72
  merge_hash.each do |key, merge_value|
60
73
  value = hash[key]
61
- if value.is_a?(Hash) && merge_value.is_a?(Hash)
62
- retval[key] = deep_merge(value, merge_value)
74
+ retval[key] = if value.is_a?(Hash) && merge_value.is_a?(Hash)
75
+ deep_merge(value, merge_value)
63
76
  else
64
- retval[key] = merge_value
77
+ merge_value
65
78
  end
66
79
  end
67
80
  retval
@@ -69,7 +82,7 @@ module FastSerializer
69
82
 
70
83
  # Convert the value to primitive data types: string, number, boolean, symbol, time, date, array, hash.
71
84
  def serialize_value(value)
72
- if value.is_a?(String) || value.is_a?(Numeric) || value == nil || value == true || value == false || value.is_a?(Symbol)
85
+ if value.is_a?(String) || value.is_a?(Numeric) || value.nil? || value == true || value == false || value.is_a?(Symbol)
73
86
  value
74
87
  elsif value.is_a?(Time) || value.is_a?(Date)
75
88
  if defined?(ActiveSupport::TimeWithZone) && value.is_a?(ActiveSupport::TimeWithZone)
@@ -97,7 +110,7 @@ module FastSerializer
97
110
  value.each do |k, v|
98
111
  val = serialize_value(v)
99
112
  if val.object_id != v.object_id
100
- hash = value.dup unless hash
113
+ hash ||= value.dup
101
114
  hash[k] = val
102
115
  end
103
116
  end
@@ -109,7 +122,7 @@ module FastSerializer
109
122
  value.each_with_index do |v, i|
110
123
  val = serialize_value(v)
111
124
  if val.object_id != v.object_id
112
- array = value.dup unless array
125
+ array ||= value.dup
113
126
  array[i] = val
114
127
  end
115
128
  end
@@ -57,7 +57,6 @@ module FastSerializer
57
57
  #
58
58
  # Serializing a nil object will result in nil rather than an empty hash.
59
59
  module Serializer
60
-
61
60
  def self.included(base)
62
61
  base.extend(ClassMethods)
63
62
  base.extend(ArrayHelper) unless base.is_a?(FastSerializer::ArraySerializer)
@@ -102,6 +101,10 @@ module FastSerializer
102
101
  #
103
102
  # Subclasses will inherit all of their parent classes serialized fields. Subclasses can override fields
104
103
  # defined on the parent class by simply defining them again.
104
+ #
105
+ # @param fields [Array<Symbol, Hash>] the fields to serialize. If the last argument is a hash, it will be
106
+ # treated as options for the serialized fields.
107
+ # @return [void]
105
108
  def serialize(*fields)
106
109
  options = {}
107
110
  if fields.size > 1 && fields.last.is_a?(Hash)
@@ -119,7 +122,7 @@ module FastSerializer
119
122
  condition = options.delete(:if)
120
123
 
121
124
  unless options.empty?
122
- raise ArgumentError.new("Unsupported serialize options: #{options.keys.join(', ')}")
125
+ raise ArgumentError.new("Unsupported serialize options: #{options.keys.join(", ")}")
123
126
  end
124
127
 
125
128
  if as && fields.size > 1
@@ -128,8 +131,8 @@ module FastSerializer
128
131
 
129
132
  fields.each do |field|
130
133
  name = as
131
- if name.nil? && field.to_s.end_with?("?".freeze)
132
- name = field.to_s.chomp("?".freeze)
134
+ if name.nil? && field.to_s.end_with?("?")
135
+ name = field.to_s.chomp("?")
133
136
  end
134
137
 
135
138
  field = field.to_sym
@@ -144,6 +147,8 @@ module FastSerializer
144
147
 
145
148
  # Remove a field from being serialized. This can be useful in subclasses if they need to remove a
146
149
  # field defined by the parent class.
150
+ #
151
+ # @param fields [Array<Symbol>] the fields to remove
147
152
  def remove(*fields)
148
153
  remove_fields = fields.collect(&:to_sym)
149
154
  field_list = []
@@ -161,6 +166,10 @@ module FastSerializer
161
166
  #
162
167
  # You can also specify the cache time to live (ttl) in seconds and the cache implementation to use.
163
168
  # Both of these values are inherited on subclasses.
169
+ #
170
+ # @param cacheable [Boolean] pass false if the serializer is not cacheable
171
+ # @param ttl [Numeric] the time to live in seconds for a cacheable serializer
172
+ # @param cache [FastSerializer::Cache] the cache implementation to use for a cacheable serializer
164
173
  def cacheable(cacheable = true, ttl: nil, cache: nil)
165
174
  @cacheable = cacheable
166
175
  self.cache_ttl = ttl if ttl
@@ -168,6 +177,8 @@ module FastSerializer
168
177
  end
169
178
 
170
179
  # Return true if the serializer class is cacheable.
180
+ #
181
+ # @return [Boolean]
171
182
  def cacheable?
172
183
  unless defined?(@cacheable)
173
184
  @cacheable = superclass.cacheable? if superclass.respond_to?(:cacheable?)
@@ -176,22 +187,27 @@ module FastSerializer
176
187
  end
177
188
 
178
189
  # Return the time to live in seconds for a cacheable serializer.
190
+ #
191
+ # @return [Numeric]
179
192
  def cache_ttl
180
193
  if defined?(@cache_ttl)
181
194
  @cache_ttl
182
195
  elsif superclass.respond_to?(:cache_ttl)
183
196
  superclass.cache_ttl
184
- else
185
- nil
186
197
  end
187
198
  end
188
199
 
189
200
  # Set the time to live on a cacheable serializer.
201
+ #
202
+ # @param value [Numeric] the time to live in seconds
203
+ # @return [void]
190
204
  def cache_ttl=(value)
191
205
  @cache_ttl = value
192
206
  end
193
207
 
194
208
  # Get the cache implemtation used to store cacheable serializers.
209
+ #
210
+ # @return [FastSerializer::Cache]
195
211
  def cache
196
212
  if defined?(@cache)
197
213
  @cache
@@ -203,6 +219,9 @@ module FastSerializer
203
219
  end
204
220
 
205
221
  # Set the cache implementation used to store cacheable serializers.
222
+ #
223
+ # @param cache [FastSerializer::Cache]
224
+ # @return [void]
206
225
  def cache=(cache)
207
226
  if defined?(ActiveSupport::Cache::Store) && cache.is_a?(ActiveSupport::Cache::Store)
208
227
  cache = Cache::ActiveSupportCache.new(cache)
@@ -222,6 +241,8 @@ module FastSerializer
222
241
  end
223
242
 
224
243
  # Return a list of the SerializedFields defined for the class.
244
+ #
245
+ # @return [Array<FastSerializer::SerializedField>]
225
246
  def serializable_fields
226
247
  unless defined?(@serializable_fields) && @serializable_fields
227
248
  fields = superclass.send(:serializable_fields).dup if superclass.respond_to?(:serializable_fields)
@@ -249,10 +270,10 @@ module FastSerializer
249
270
  field_list = []
250
271
  added = false
251
272
  serializable_fields.each do |existing_field|
252
- if existing_field.name == name
253
- field_list << field
273
+ field_list << if existing_field.name == name
274
+ field
254
275
  else
255
- field_list << existing_field
276
+ existing_field
256
277
  end
257
278
  end
258
279
  field_list << field unless added
@@ -261,14 +282,14 @@ module FastSerializer
261
282
 
262
283
  # Define a delegate method name +attribute+ that invokes the +field+ method on the wrapped object.
263
284
  def define_delegate(attribute, field)
264
- define_method(attribute){ object.send(field) }
285
+ define_method(attribute) { object.send(field) }
265
286
  end
266
287
  end
267
288
 
268
289
  module ArrayHelper
269
290
  # Helper method to serialize an array of values using this serializer.
270
291
  def array(values, options = nil)
271
- options = (options ? options.merge(:serializer => self) : {:serializer => self})
292
+ options = (options ? options.merge(serializer: self) : {serializer: self})
272
293
  FastSerializer::ArraySerializer.new(values, options)
273
294
  end
274
295
  end
@@ -295,14 +316,12 @@ module FastSerializer
295
316
  # Serialize the wrapped object into a format suitable for passing to a JSON parser.
296
317
  def as_json(*args)
297
318
  return nil unless object
298
- unless @_serialized
299
- @_serialized = (cacheable? ? load_from_cache : load_hash).freeze
300
- end
319
+ @_serialized ||= (cacheable? ? load_from_cache : load_hash).freeze
301
320
  @_serialized
302
321
  end
303
322
 
304
- alias :to_hash :as_json
305
- alias :to_h :as_json
323
+ alias_method :to_hash, :as_json
324
+ alias_method :to_h, :as_json
306
325
 
307
326
  # Convert the wrapped object to JSON format.
308
327
  def to_json(options = {})
@@ -363,7 +382,7 @@ module FastSerializer
363
382
  name = field.name
364
383
 
365
384
  if field.optional?
366
- next unless include_fields && include_fields.include?(name)
385
+ next unless include_fields&.include?(name)
367
386
  end
368
387
  next if excluded_fields && excluded_fields[name] == true
369
388
  condition = field.condition
@@ -419,7 +438,7 @@ module FastSerializer
419
438
  end
420
439
  hash_key
421
440
  elsif options.is_a?(Enumerable)
422
- options.collect{|option| options_cache_key(option)}
441
+ options.collect { |option| options_cache_key(option) }
423
442
  else
424
443
  options
425
444
  end
@@ -1,24 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
- require 'time'
5
- require 'date'
3
+ require "json"
4
+ require "time"
5
+ require "date"
6
6
 
7
7
  module FastSerializer
8
- require_relative 'fast_serializer/cache'
9
- require_relative 'fast_serializer/cache/active_support_cache'
10
- require_relative 'fast_serializer/serialization_context'
11
- require_relative 'fast_serializer/serialized_field'
12
- require_relative 'fast_serializer/serializer'
13
- require_relative 'fast_serializer/array_serializer'
8
+ require_relative "fast_serializer/cache"
9
+ require_relative "fast_serializer/cache/active_support_cache"
10
+ require_relative "fast_serializer/serialization_context"
11
+ require_relative "fast_serializer/serialized_field"
12
+ require_relative "fast_serializer/serializer"
13
+ require_relative "fast_serializer/array_serializer"
14
14
 
15
15
  class << self
16
16
  @cache = nil
17
17
 
18
18
  # Get the global cache implementation used for storing cacheable serializers.
19
- def cache
20
- @cache
21
- end
19
+ attr_reader :cache
22
20
 
23
21
  # Set the global cache implementation used for storing cacheable serializers.
24
22
  # The cache implementation should implement the +fetch+ method as defined in
@@ -26,6 +24,8 @@ module FastSerializer
26
24
  #
27
25
  # In a Rails app, you can initialize the cache by simply passing in the value :rails
28
26
  # to use the default Rails.cache. You can also directly pass in an ActiveSupportCache::Store.
27
+ #
28
+ # @param cache [FastSerializer::Cache, ActiveSupport::Cache::Store, Symbol] the cache to use
29
29
  def cache=(cache)
30
30
  if cache == :rails
31
31
  cache = Cache::ActiveSupportCache.new(Rails.cache)