barley 0.5 → 0.6.1

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: 4808cb10061c5a86be6edbf532a6fb041519e4b7b4a08b770e0d63854a5f61e1
4
- data.tar.gz: 5ccb1ed50e9d440a0bb3e9c006280e970b70b5ecc64afb7b8660c0d326f58239
3
+ metadata.gz: 80e724f1d510a0774072dab90c06262278a06fd49adff8a77314852c2aafbe7f
4
+ data.tar.gz: a13898b638153e90c95c25d0558c54e63b2514c6095be81c5755fb5d92dbb544
5
5
  SHA512:
6
- metadata.gz: 4562ae18d898be75d1abf2d2872bd5f79333f38e6a3e111548624ba6e4b19f4f7316087e36ff35f9103cac56a6b96e9d2f1fb32d1cfb1596430e1b81a1f68c2a
7
- data.tar.gz: 13c86fbcb1d2678165bd128ea0e57ca80e1e4d63e3a3ccee09f9ac85838bab7cd0894d75cc832c7a513ac29fd697573039b8ee5a1621be1152e2a22c6525b5ce
6
+ metadata.gz: da037e1c4749228e9fa48db4dcc00a8b614ebac1acc5ba0646c61fce0b77a377e530581b7536bc08b3111747ed6303ce60d3a275ac4c8cef2231a1ef726d873b
7
+ data.tar.gz: 49b297c3db282da63110f28d9599157ac91f50c7fec42916e4a387c20ef0010ebfd3e4b4c53b03baa61985cdf17cdd7b79412eb388551d7c5a58d2c5f00b36b3
data/README.md CHANGED
@@ -4,9 +4,9 @@
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
- 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.
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
 
11
11
  You don't believe us? Check out the [benchmarks](#benchmarks). 😎
12
12
 
@@ -28,26 +28,30 @@ Then define your attributes and associations in a serializer class.
28
28
  ```ruby
29
29
  # /app/serializers/user_serializer.rb
30
30
  class UserSerializer < Barley::Serializer
31
-
31
+
32
32
  attributes id: Types::Strict::Integer, :name
33
-
33
+
34
34
  attribute :email
35
35
  attribute :value, type: Types::Coercible::Integer
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
42
-
46
+
43
47
  one :profile, cache: { expires_in: 1.day } do
44
48
  attributes :avatar, :social_url
45
-
49
+
46
50
  attribute :badges do
47
51
  object.badges.map(&:display_name)
48
52
  end
49
53
  end
50
-
54
+
51
55
  end
52
56
  ```
53
57
 
@@ -85,7 +89,7 @@ You can also define the serializer class with the `serializer` macro.
85
89
  # /app/models/user.rb
86
90
  class User < ApplicationRecord
87
91
  include Barley::Serializable
88
-
92
+
89
93
  serializer UserSerializer
90
94
  end
91
95
  ```
@@ -139,12 +143,12 @@ You can define a custom serializer for the association with the `serializer` opt
139
143
 
140
144
  You can of course define serializers with inner classes for simple needs.
141
145
 
142
- ```ruby
146
+ ```ruby
143
147
  class UserSerializer < Barley::Serializer
144
148
  attributes :id, :name, :email, :created_at, :updated_at
145
149
 
146
150
  one :group, serializer: LocalGroupSerializer
147
-
151
+
148
152
  class LocalGroupSerializer < Barley::Serializer
149
153
  attributes :id, :name
150
154
  end
@@ -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
 
@@ -193,21 +208,30 @@ Feel like using a block to define your associations? You can do that too.
193
208
  ```ruby
194
209
  many :posts do
195
210
  attributes :id, :title, :body
196
-
211
+
197
212
  one :author do
198
213
  attributes :name, :email
199
214
  end
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
+
203
226
  ## Context
227
+
204
228
  You can pass a context to the serializer with the `with_context` method.
205
229
 
206
230
  ```ruby
207
231
  serializer = PostSerializer.new(Post.last).with_context(current_user: current_user)
208
232
  ```
209
233
 
210
- This context will be available in the serializer with the `context` method.
234
+ This context will be available in the serializer with the `context` method. It is also available in nested serializers.
211
235
 
212
236
  ```ruby
213
237
  class PostSerializer < Barley::Serializer
@@ -216,14 +240,31 @@ class PostSerializer < Barley::Serializer
216
240
  attribute :is_owner do
217
241
  object.user == context.current_user
218
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
219
251
  end
220
252
  ```
221
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
+
222
263
  ## Generators
223
264
  You have two generators available. One to generate the serializer class:
224
265
 
225
266
  ```shell
226
- rails generate barley:serializer User
267
+ rails generate barley:serializer User
227
268
  # or
228
269
  rails generate barley:serializer User --name=CustomUserSerializer
229
270
  ```
@@ -277,7 +318,7 @@ end
277
318
  ```
278
319
 
279
320
  ## Type checking
280
- Barley can check the type of the object you are serializing with the [dry-types](https://dry-rb.org/gems/dry-types/main/) gem.
321
+ Barley can check the type of the object you are serializing with the [dry-types](https://dry-rb.org/gems/dry-types/main/) gem.
281
322
 
282
323
  It will raise an error if the object is not of the expected type, or coerce it to the correct type and perform constraints checks.
283
324
 
@@ -304,7 +345,7 @@ You will soon be able to replace all occurrences of `Serializer` with `Cerealize
304
345
  # /app/models/user.rb
305
346
  class User < ApplicationRecord
306
347
  include Barley::Cerealizable
307
-
348
+
308
349
  cerealizer UserCerealizer
309
350
  end
310
351
 
@@ -128,7 +128,7 @@ module Barley
128
128
  return {} if element.nil?
129
129
 
130
130
  el_serializer = serializer || element.serializer.class
131
- el_serializer.new(element, cache: cache).serializable_hash
131
+ el_serializer.new(element, cache: cache, context: @context).serializable_hash
132
132
  end
133
133
  self.defined_attributes = (defined_attributes || []) << key_name
134
134
  end
@@ -161,12 +161,20 @@ module Barley
161
161
  # many :groups, cache: {expires_in: 1.hour}
162
162
  # # => {groups: [{id: 1234, name: "Group 1"}, {id: 5678, name: "Group 2"}]}
163
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"}]}
164
171
  # @param key [Symbol] the association name
165
172
  # @param key_name [Symbol] the key name in the hash
166
173
  # @param serializer [Class] the serializer to use
167
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, Proc] the scope to use to fetch the elements
168
176
  # @param block [Proc] a block to use to define the serializer inline
169
- 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)
170
178
  key_name ||= key
171
179
  if block
172
180
  serializer = Class.new(Barley::Serializer) do
@@ -175,10 +183,15 @@ module Barley
175
183
  end
176
184
  define_method(key_name) do
177
185
  elements = object.send(key)
186
+ if scope.is_a?(Symbol)
187
+ elements = elements.send(scope)
188
+ elsif scope.is_a?(Proc)
189
+ elements = elements.instance_exec(&scope)
190
+ end
178
191
  return [] if elements.empty?
179
192
 
180
193
  el_serializer = serializer || elements.first.serializer.class
181
- elements.map { |element| el_serializer.new(element, cache: cache).serializable_hash }.reject(&:blank?)
194
+ elements.map { |element| el_serializer.new(element, cache: cache, context: @context).serializable_hash }.reject(&:blank?)
182
195
  end
183
196
  self.defined_attributes = (defined_attributes || []) << key_name
184
197
  end
@@ -193,8 +206,10 @@ module Barley
193
206
  # @param object [Object] the object to serialize
194
207
  # @param cache [Boolean, Hash<Symbol, ActiveSupport::Duration>] a boolean to cache the result, or a hash with options for the cache
195
208
  # @param root [Boolean] whether to include the root key in the hash
196
- def initialize(object, cache: false, root: false)
209
+ # @param context [Object] an optional context object to pass additional data to the serializer
210
+ def initialize(object, cache: false, root: false, context: nil)
197
211
  @object = object
212
+ @context = context
198
213
  @root = root
199
214
  @cache, @expires_in = if cache.is_a?(Hash)
200
215
  [true, cache[:expires_in]]
@@ -1,3 +1,3 @@
1
1
  module Barley
2
- VERSION = "0.5"
2
+ VERSION = "0.6.1"
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.5'
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cedric Delalande
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-19 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.