barley 0.4.1 → 0.6

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: d882b89bf1bf77259eda96813c4732ef1b286142ecb29fcb945837b743e089c9
4
- data.tar.gz: 87dc3b213a614957a668c08865b87eb44f805cf76b79a60c710025a7d18257d8
3
+ metadata.gz: 4143d89558b7c17c5c0ca1c0fc3fc20083b178a79ecdbc957e6cc3a0dc170189
4
+ data.tar.gz: 0d3c0c2c74ea618a5df4a4ed29155f625ee58836024112816aa5055c3c064531
5
5
  SHA512:
6
- metadata.gz: a7eb159a6e40374364504f5c828d7e1f82e7a581bd89fe374182916b0dbc6863caaea779acf409e58c8fe60ff3614acdfa944bb3f74dbd808957925db146dded
7
- data.tar.gz: d84b0157c80e83cfa28dbafda0fd300f2774c4362b5e1e47f9fc0381fb0cd8713dce2f1b27f4cfb9896af2c11d354d92b8df0dcfaee6a94bb69e6aca738e45b2
6
+ metadata.gz: 68d5f3bd3ba0a85e4d9365fa928fe425323bd469fc11e68e60ecbc8d3f52f078c2a449109446668c18750d18633b9de6ce3f4478d82db41c0847b1ec49289236
7
+ data.tar.gz: 7ab87897947545f171ce458042c63deecfb6e22555cfc97e508d2233215360ac78d804a32d8bf46bd73e9edac3104622e3831203263056cf70a1085401d908cb
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Gem Version](https://badge.fury.io/rb/barley.svg)](https://badge.fury.io/rb/barley)
5
5
  ![Static Badge](https://img.shields.io/badge/Cereal%20-%20100%25%20-%20darklime)
6
6
 
7
- Barley is a dead simple, fast, and efficient ActiveModel serializer.
7
+ Barley is a fast and efficient ActiveModel serializer.
8
8
 
9
9
  Cerealize your ActiveModel objects into flat hashes with a dead simple, yet versatile DSL, and caching and type-checking baked in. Our daily bread is to make your API faster.
10
10
 
@@ -36,6 +36,10 @@ class UserSerializer < Barley::Serializer
36
36
 
37
37
  many :posts
38
38
 
39
+ many :posts, key_name: :featured, scope: :featured
40
+
41
+ many :posts, key_name: :popular, scope: -> { where("views > 10_000").limit(3) }
42
+
39
43
  one :group, serializer: CustomGroupSerializer
40
44
 
41
45
  many :related_users, key: :friends, cache: true
@@ -174,6 +178,17 @@ You can define a custom serializer for the association with the `serializer` opt
174
178
  many :posts, serializer: CustomPostSerializer, cache: { expires_in: 1.hour }
175
179
  ```
176
180
 
181
+ ##### Scope
182
+ You can pass a scope to the association with the `scope` option. It can either be a symbol referencing a named scope on your associated model, or a lambda.
183
+
184
+ ```ruby
185
+ many :posts, scope: :published # given you have a scope named `published` on your Post model
186
+ ```
187
+
188
+ ```ruby
189
+ many :posts, scope: -> { where(published: true).limit(4) }
190
+ ```
191
+
177
192
  ##### Key name
178
193
  You can also pass a key name for the association with the `key_name` option.
179
194
 
@@ -200,6 +215,51 @@ Feel like using a block to define your associations? You can do that too.
200
215
  end
201
216
  ```
202
217
 
218
+ Of course, all the options available for the `one` and `many` macros are also available for the block syntax.
219
+
220
+ ```ruby
221
+ many :posts, key_name: :featured do
222
+ attributes :id, :title, :body
223
+ end
224
+ ```
225
+
226
+ ## Context
227
+
228
+ You can pass a context to the serializer with the `with_context` method.
229
+
230
+ ```ruby
231
+ serializer = PostSerializer.new(Post.last).with_context(current_user: current_user)
232
+ ```
233
+
234
+ This context will be available in the serializer with the `context` method. It is also available in nested serializers.
235
+
236
+ ```ruby
237
+ class PostSerializer < Barley::Serializer
238
+ attributes :id, :title, :body
239
+
240
+ attribute :is_owner do
241
+ object.user == context.current_user
242
+ end
243
+
244
+ many :comments do
245
+ many :likes do
246
+ attribute :is_owner do
247
+ object.user == context.current_user # context is here too!
248
+ end
249
+ end
250
+ end
251
+ end
252
+ ```
253
+
254
+ ### Using a custom context object
255
+ Barley generates a Struct from the context hash you pass to the with_context method. But you can also pass a custom context object directly in the initializer instead.
256
+
257
+ ```ruby
258
+ my_context = Struct.new(:current_user).new(current_user)
259
+
260
+ serializer = PostSerializer.new(Post.last, context: my_context)
261
+ ```
262
+
203
263
  ## Generators
204
264
  You have two generators available. One to generate the serializer class:
205
265
 
@@ -3,6 +3,7 @@
3
3
  module Barley
4
4
  class Serializer
5
5
  attr_accessor :object
6
+ attr_accessor :context
6
7
 
7
8
  class << self
8
9
  attr_accessor :defined_attributes
@@ -127,7 +128,7 @@ module Barley
127
128
  return {} if element.nil?
128
129
 
129
130
  el_serializer = serializer || element.serializer.class
130
- el_serializer.new(element, cache: cache).serializable_hash
131
+ el_serializer.new(element, cache: cache, context: @context).serializable_hash
131
132
  end
132
133
  self.defined_attributes = (defined_attributes || []) << key_name
133
134
  end
@@ -160,12 +161,20 @@ module Barley
160
161
  # many :groups, cache: {expires_in: 1.hour}
161
162
  # # => {groups: [{id: 1234, name: "Group 1"}, {id: 5678, name: "Group 2"}]}
162
163
  #
164
+ # @example using a named scope
165
+ # many :groups, scope: :active # given the scope `active` is defined in the Group model
166
+ # # => {groups: [{id: 5678, name: "Group 2"}]}
167
+ #
168
+ # @example using a lambda scope
169
+ # many :groups, scope: -> { order(id: :asc).limit(1) }
170
+ # # => {groups: [{id: 1234, name: "Group 1"}]}
163
171
  # @param key [Symbol] the association name
164
172
  # @param key_name [Symbol] the key name in the hash
165
173
  # @param serializer [Class] the serializer to use
166
174
  # @param cache [Boolean, Hash<Symbol, ActiveSupport::Duration>] whether to cache the result, or a hash with options for the cache
175
+ # @param scope [Symbol] the scope to use to fetch the elements
167
176
  # @param block [Proc] a block to use to define the serializer inline
168
- def many(key, key_name: nil, serializer: nil, cache: false, &block)
177
+ def many(key, key_name: nil, serializer: nil, cache: false, scope: nil, &block)
169
178
  key_name ||= key
170
179
  if block
171
180
  serializer = Class.new(Barley::Serializer) do
@@ -177,7 +186,7 @@ module Barley
177
186
  return [] if elements.empty?
178
187
 
179
188
  el_serializer = serializer || elements.first.serializer.class
180
- elements.map { |element| el_serializer.new(element, cache: cache).serializable_hash }.reject(&:blank?)
189
+ elements.map { |element| el_serializer.new(element, cache: cache, context: @context).serializable_hash }.reject(&:blank?)
181
190
  end
182
191
  self.defined_attributes = (defined_attributes || []) << key_name
183
192
  end
@@ -192,8 +201,10 @@ module Barley
192
201
  # @param object [Object] the object to serialize
193
202
  # @param cache [Boolean, Hash<Symbol, ActiveSupport::Duration>] a boolean to cache the result, or a hash with options for the cache
194
203
  # @param root [Boolean] whether to include the root key in the hash
195
- def initialize(object, cache: false, root: false)
204
+ # @param context [Object] an optional context object to pass additional data to the serializer
205
+ def initialize(object, cache: false, root: false, context: nil)
196
206
  @object = object
207
+ @context = context
197
208
  @root = root
198
209
  @cache, @expires_in = if cache.is_a?(Hash)
199
210
  [true, cache[:expires_in]]
@@ -224,6 +235,25 @@ module Barley
224
235
  Barley::Cache.delete(key)
225
236
  end
226
237
 
238
+ # Sets the context object for the serializer
239
+ #
240
+ # The context object is a Struct built from the given arguments.
241
+ # It can be used to pass additional data to the serializer. The context object is accessible in the serializer with the `context` attribute.
242
+ # @example
243
+ # serializer.with_context(current_user: current_user, locale: I18n.locale)
244
+ # # => #<Barley::Serializer:0x00007f8f3b8b3e08 @object=#<Product id: 1, name: "Product 1">, @context=#<struct current_user=1, locale=:en>>
245
+ # # In the serializer:
246
+ # attribute :name do
247
+ # "#{object.name[context.locale]}" # Will use the locale from the context
248
+ # end
249
+ # @param args [Hash] the context object attributes
250
+ # @return [Barley::Serializer] the serializer
251
+ def with_context(**args)
252
+ @context = Struct.new(*args.keys).new(*args.values)
253
+
254
+ self
255
+ end
256
+
227
257
  private
228
258
 
229
259
  # @api private
@@ -247,15 +277,15 @@ module Barley
247
277
  # Serializes the object
248
278
  #
249
279
  # @api private
280
+ # @raise [Barley::Error] if no attribute or relation is defined in the serializer
250
281
  #
251
282
  # @return [Hash] the serializable hash
252
283
  def _serializable_hash
253
- hash = {}
284
+ raise Barley::Error, "No attribute or relation defined in #{self.class}" if defined_attributes.blank?
254
285
 
255
- defined_attributes.each do |key|
256
- hash[key] = send(key)
286
+ hash = defined_attributes.each_with_object({}) do |key, result|
287
+ result[key] = send(key)
257
288
  end
258
-
259
289
  @root ? {root_key => hash} : hash
260
290
  end
261
291
 
@@ -1,3 +1,3 @@
1
1
  module Barley
2
- VERSION = "0.4.1"
2
+ VERSION = "0.6"
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.4.1
4
+ version: '0.6'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cedric Delalande
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-10-27 00:00:00.000000000 Z
11
+ date: 2024-06-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -92,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
92
92
  - !ruby/object:Gem::Version
93
93
  version: '0'
94
94
  requirements: []
95
- rubygems_version: 3.3.26
95
+ rubygems_version: 3.3.27
96
96
  signing_key:
97
97
  specification_version: 4
98
98
  summary: Barley is a dead simple, fast, and efficient ActiveModel serializer.