barley 0.8 → 0.9.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6da2835a5aa80d5ad8df847a595c104a92d1b0a34146f648368acfc95d98712f
4
- data.tar.gz: 1c2b3c65b17e99f95d80f2842b2a7e99a73d93cdecd91b62943f1c9a6ff3e463
3
+ metadata.gz: 65659a284da526170cf31f02c88e4e1f8a9739bd2a74db1efcaed57c6a142ed1
4
+ data.tar.gz: 0d23f80698d7f723a9e86bc7bbf9930a18d999fe7c2b923ec3bcff4cf08b6223
5
5
  SHA512:
6
- metadata.gz: 5feba636b2205ce2b1be958e00d62e04509bec4d441405fcb669b76c455cd2209bddce0fc8ceedfa3a44f7251f22d1449b5315b6abcbf96cc0d85ac6924f903e
7
- data.tar.gz: '08010326d833ba31944fddc5cf90c82db6a8002c0d8c2ae1f22dc2c137b1169b2f2841e58ec64daff403583ed08dacc4b2ad33dffa75a2ff5b270d69b67c1687'
6
+ metadata.gz: 7c1783516b1805df6d02a424791d6148852d429e987f3c0d090345ed01085a7e1777c0748791efa8a0d79fc55711fb27c209d61aa1e1724c49ee34f2b0cbd488
7
+ data.tar.gz: f4de8fb9cfdb8f034dae1d64e0cc4732e2a00a6d308848070b27c79d52a6ae8d23faf65be6dc420c9971b823a70b6227561e507e997dddd5396f5f200e640936
data/README.md CHANGED
@@ -299,7 +299,7 @@ user = User.find(1)
299
299
  user.as_json(serializer: CustomUserSerializer, cache: { expires_in: 1.hour })
300
300
  ```
301
301
 
302
- Beware, this gem overrides the `as_json` method on your model. Calling `as_json` with `include`, `only`, or `except` options will not work.
302
+ Beware, this gem overrides the `as_json` method on your model. Calling `as_json` with `include`, `only`, or `except` options will not work as expected.
303
303
 
304
304
  Why? We believe it defeats the purpose of this gem. If you want to customize the serialization of your model, you should use a serializer class.
305
305
 
@@ -1,3 +1,4 @@
1
+ require "rails/engine"
1
2
  module Barley
2
3
  class Railtie < ::Rails::Railtie
3
4
  end
@@ -65,7 +65,8 @@ module Barley
65
65
  cache = options[:cache] || false
66
66
  root = options[:root] || false
67
67
  begin
68
- serializer.new(self, cache: cache, root: root, only: options[:only], except: options[:except]).serializable_hash
68
+ serializer.new(self, cache: cache, root: root).serializable_hash
69
+ .as_json(only: options[:only], except: options[:except])
69
70
  rescue NameError
70
71
  raise Barley::Error, "Could not find serializer for #{self}. Please define a #{serializer} class."
71
72
  end
@@ -2,8 +2,10 @@
2
2
 
3
3
  module Barley
4
4
  class Serializer
5
- attr_accessor :object
6
- attr_accessor :context
5
+ EMPTY_ARRAY = [].freeze
6
+ EMPTY_HASH = {}.freeze
7
+
8
+ attr_accessor :object, :context
7
9
 
8
10
  class << self
9
11
  attr_accessor :defined_attributes
@@ -81,7 +83,10 @@ module Barley
81
83
  if type.nil?
82
84
  value
83
85
  else
84
- raise Barley::InvalidAttributeError, "Invalid value type found for attribute #{key_name}::#{type.name}: #{value}::#{value.class}" unless type.valid?(value)
86
+ unless type.valid?(value)
87
+ raise Barley::InvalidAttributeError,
88
+ "Invalid value type found for attribute #{key_name}::#{type.name}: #{value}::#{value.class}"
89
+ end
85
90
 
86
91
  type[value]
87
92
  end
@@ -125,19 +130,21 @@ module Barley
125
130
  # @param block [Proc] a block to use to define the serializer inline
126
131
  def one(key, key_name: nil, serializer: nil, cache: false, &block)
127
132
  key_name ||= key
128
- if block
129
- serializer = Class.new(Barley::Serializer) do
133
+ resolved_serializer = serializer
134
+ resolved_serializer_from_block = nil
135
+ if block && !serializer
136
+ resolved_serializer_from_block = Class.new(Barley::Serializer) do
130
137
  instance_eval(&block)
131
138
  end
132
139
  end
140
+
133
141
  define_method(key_name) do
134
142
  element = object.send(key)
135
- return {} if element.nil?
143
+ return EMPTY_HASH if element.nil?
136
144
 
137
- el_serializer = serializer || element.serializer.class
138
- only = @only.find { |k| k.is_a?(Hash) && k.key?(key) }.slice(key).values.first if @only.present?
139
- except = @except.find { |k| k.is_a?(Hash) && k.key?(key) }.slice(key).values.first if @except.present?
140
- el_serializer.new(element, cache: cache, context: @context, only: only, except: except).serializable_hash
145
+ el_serializer = resolved_serializer || resolved_serializer_from_block || element.serializer.class
146
+
147
+ el_serializer.new(element, cache: cache, context: @context).serializable_hash
141
148
  end
142
149
  self.defined_attributes = (defined_attributes || []) << key_name
143
150
  end
@@ -185,28 +192,47 @@ module Barley
185
192
  # @param block [Proc] a block to use to define the serializer inline
186
193
  def many(key, key_name: nil, serializer: nil, cache: false, scope: nil, &block)
187
194
  key_name ||= key
188
- if block
189
- serializer = Class.new(Barley::Serializer) do
195
+ resolved_serializer = serializer
196
+ resolved_serializer_from_block = nil
197
+ if block && !serializer
198
+ resolved_serializer_from_block = Class.new(Barley::Serializer) do
190
199
  instance_eval(&block)
191
200
  end
192
201
  end
202
+
193
203
  define_method(key_name) do
194
204
  elements = object.send(key)
195
- if scope.is_a?(Symbol)
196
- elements = elements.send(scope)
197
- elsif scope.is_a?(Proc)
198
- elements = if scope.arity == 1
199
- elements.instance_exec(@context, &scope)
200
- else
201
- elements.instance_exec(&scope)
202
- end
205
+ return EMPTY_ARRAY if elements.nil? || (elements.respond_to?(:empty?) && elements.empty?)
206
+
207
+ if scope
208
+ elements = if scope.is_a?(Symbol)
209
+ elements.send(scope)
210
+ else
211
+ (if scope.arity == 1
212
+ elements.instance_exec(@context, &scope)
213
+ else
214
+ elements.instance_exec(&scope)
215
+ end)
216
+ end
217
+ end
218
+ return EMPTY_ARRAY if elements.empty?
219
+
220
+ el_serializer_class = resolved_serializer || resolved_serializer_from_block || element.serializer.class
221
+ serializer_instance = el_serializer_class.new(nil, cache: cache, context: @context)
222
+
223
+ result = []
224
+ elements.each do |element|
225
+ serializer_instance.object = element
226
+ # This assumes _serializable_hash primarily depends on @object,
227
+ # @context, and @effective_options (set during its own init).
228
+ serialized = serializer_instance.send(:_serializable_hash) # Use send for private method
229
+
230
+ next if serialized.nil? || (serialized.respond_to?(:empty?) && serialized.empty?)
231
+
232
+ result << serialized
203
233
  end
204
- return [] if elements.empty?
205
234
 
206
- el_serializer = serializer || elements.first.serializer.class
207
- only = @only.find { |k| k.is_a?(Hash) && k.key?(key) }.slice(key).values.first if @only.present?
208
- except = @except.find { |k| k.is_a?(Hash) && k.key?(key) }.slice(key).values.first if @except.present?
209
- elements.map { |element| el_serializer.new(element, cache: cache, context: @context, only: only, except: except).serializable_hash }.reject(&:blank?)
235
+ result
210
236
  end
211
237
  self.defined_attributes = (defined_attributes || []) << key_name
212
238
  end
@@ -222,41 +248,29 @@ module Barley
222
248
  # @param cache [Boolean, Hash<Symbol, ActiveSupport::Duration>] a boolean to cache the result, or a hash with options for the cache
223
249
  # @param root [Boolean] whether to include the root key in the hash
224
250
  # @param context [Object] an optional context object to pass additional data to the serializer
225
- # @param only [Array<Symbol>] an array of attributes to include
226
- # @param except [Array<Symbol>] an array of attributes to exclude
227
- def initialize(object, cache: false, root: false, context: nil, only: nil, except: nil)
251
+ def initialize(object, cache: false, root: false, context: nil)
228
252
  @object = object
229
253
  @context = context
230
254
  @root = root
231
- @only = only
232
- @except = except
233
255
  @cache, @expires_in = if cache.is_a?(Hash)
234
- [true, cache[:expires_in]]
235
- else
236
- [cache, nil]
237
- end
256
+ [true, cache[:expires_in]]
257
+ else
258
+ [cache, nil]
259
+ end
238
260
  end
239
261
 
240
262
  # Serializes the object
241
263
  #
242
264
  # @return [Hash] the serializable hash
243
265
  def serializable_hash
244
- hash = if @cache
266
+ # Cache check first
267
+ if @cache
245
268
  Barley::Cache.fetch(cache_base_key, expires_in: @expires_in) do
246
269
  _serializable_hash
247
270
  end
248
271
  else
249
272
  _serializable_hash
250
273
  end
251
- if @only.present?
252
- only = @only.map { |k| k.is_a?(Hash) ? k.keys.first : k }
253
- hash.slice!(*only)
254
- end
255
- if @except.present?
256
- except = @except.reject { |k| k.is_a?(Hash) }
257
- hash.except!(*except)
258
- end
259
- hash
260
274
  end
261
275
 
262
276
  # Clears the cache for the object
@@ -293,7 +307,7 @@ module Barley
293
307
  #
294
308
  # @return [String] the cache key
295
309
  def cache_base_key
296
- if object.updated_at.present?
310
+ if object.respond_to?(:updated_at) && object.updated_at.present?
297
311
  "#{object.class.name&.underscore}/#{object.id}/#{object.updated_at&.to_i}/barley_cache/"
298
312
  else
299
313
  "#{object.class.name&.underscore}/#{object.id}/barley_cache/"
@@ -314,19 +328,25 @@ module Barley
314
328
  #
315
329
  # @return [Hash] the serializable hash
316
330
  def _serializable_hash
317
- raise Barley::Error, "No attribute or relation defined in #{self.class}" if defined_attributes.blank?
331
+ attrs = defined_attributes
332
+ raise Barley::Error, 'No attribute or relation defined in the serializer' if attrs.nil?
318
333
 
319
- hash = defined_attributes.each_with_object({}) do |key, result|
320
- result[key] = send(key)
334
+ return @root ? { root_key => EMPTY_HASH } : EMPTY_HASH if attrs.nil? || attrs.empty?
335
+
336
+ hash = {}
337
+ attrs.each do |key|
338
+ value = send(key)
339
+ hash[key] = value unless value.nil?
321
340
  end
322
- @root ? {root_key => hash} : hash
341
+
342
+ @root ? { root_key => hash } : hash
323
343
  end
324
344
 
325
345
  # @api private
326
346
  #
327
347
  # @return [Symbol] the root key, based on the class name
328
348
  def root_key
329
- object.class.name.underscore.to_sym
349
+ @root_key = object_class.name.underscore.to_sym
330
350
  end
331
351
  end
332
352
  end
@@ -1,3 +1,3 @@
1
1
  module Barley
2
- VERSION = '0.8'
2
+ VERSION = "0.9.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: barley
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.8'
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cedric Delalande
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-25 00:00:00.000000000 Z
11
+ date: 2025-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-types