barley 0.4.1 → 0.6

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: 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.