alba 2.3.0 → 2.4.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 +4 -4
- data/.editorconfig +10 -0
- data/.rubocop.yml +12 -2
- data/CHANGELOG.md +11 -0
- data/Gemfile +2 -2
- data/README.md +153 -5
- data/alba.gemspec +1 -1
- data/lib/alba/association.rb +7 -3
- data/lib/alba/conditional_attribute.rb +1 -0
- data/lib/alba/default_inflector.rb +13 -1
- data/lib/alba/deprecation.rb +2 -1
- data/lib/alba/layout.rb +1 -0
- data/lib/alba/nested_attribute.rb +1 -0
- data/lib/alba/resource.rb +35 -7
- data/lib/alba/typed_attribute.rb +1 -0
- data/lib/alba/version.rb +1 -1
- data/lib/alba.rb +3 -3
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89ce66083a51c7811468f9435288afbc53f81418f21635af4393eaf1ac635d14
|
4
|
+
data.tar.gz: 7344d77ba35c156a6a18abe6f5ff498b7a8cd24b460c5b3f6bf1f0739bd0c8aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33e534a676d589ba88db064b8ba57bbd10a20d268c417d8ed89fbc9b830f2861e4d3c1b46772d9151fce5dcff909e591f26f4fe1be77c247da4e1ceb4998d1cc
|
7
|
+
data.tar.gz: 401030ee3033228b11d2b75fa411809e7707b0c8b6791c2fe9da8bf9ce290c290225cb4e23895bc31019cc8cead19ac20335fffb24682c58ebc7f09a8250999a
|
data/.editorconfig
ADDED
data/.rubocop.yml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
|
3
3
|
inherit_gem:
|
4
|
-
rubocop-
|
4
|
+
rubocop-gem_dev: 'config/rubocop.yml'
|
5
5
|
|
6
6
|
inherit_mode:
|
7
7
|
merge:
|
@@ -18,6 +18,7 @@ AllCops:
|
|
18
18
|
- 'Rakefile'
|
19
19
|
- 'alba.gemspec'
|
20
20
|
- 'benchmark/**/*.rb'
|
21
|
+
- 'docs/**/*'
|
21
22
|
- 'script/**/*.rb'
|
22
23
|
NewCops: enable
|
23
24
|
EnabledByDefault: true
|
@@ -32,6 +33,10 @@ Layout/ClassStructure:
|
|
32
33
|
Exclude:
|
33
34
|
- 'test/**/*'
|
34
35
|
|
36
|
+
# LineLength 80 comes from restrictions in good old days.
|
37
|
+
Layout/LineLength:
|
38
|
+
Max: 160
|
39
|
+
|
35
40
|
# We'd like to write something like:
|
36
41
|
# assert_equal(
|
37
42
|
# expected,
|
@@ -73,6 +78,11 @@ Metrics/ParameterLists:
|
|
73
78
|
Minitest/EmptyLineBeforeAssertionMethods:
|
74
79
|
Enabled: false
|
75
80
|
|
81
|
+
# By nature of that test
|
82
|
+
Minitest/NoTestCases:
|
83
|
+
Exclude:
|
84
|
+
- 'test/dependencies/test_dependencies.rb'
|
85
|
+
|
76
86
|
# We need to eval resource code to test errors on resource classes
|
77
87
|
Security/Eval:
|
78
88
|
Exclude:
|
@@ -109,7 +119,7 @@ Style/InlineComment:
|
|
109
119
|
Enabled: false
|
110
120
|
|
111
121
|
Style/MethodCallWithArgsParentheses:
|
112
|
-
AllowedMethods: ['require', 'require_relative', 'include', 'extend', 'puts', 'p', 'warn', 'raise', 'send', 'public_send']
|
122
|
+
AllowedMethods: ['require', 'require_relative', 'include', 'extend', 'puts', 'p', 'warn', 'raise', 'send', 'public_send', 'alias_method']
|
113
123
|
Exclude:
|
114
124
|
# There are so many `attributes` call without parenthese and that's absolutely fine
|
115
125
|
- 'test/**/*.rb'
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
6
6
|
|
7
7
|
## [Unreleased]
|
8
8
|
|
9
|
+
## [2.4.0] 2023-08-02
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Implement helper [#322](https://github.com/okuramasafumi/alba/pull/322)
|
14
|
+
- Add `prefer_resource_method!` [#323](https://github.com/okuramasafumi/alba/pull/323)
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
|
18
|
+
- Fix the bug of resource name inference [No PR](https://github.com/okuramasafumi/alba/commit/dab7091efa4a76ce9e538e08efa7349c296a705c)
|
19
|
+
|
9
20
|
## [2.3.0] 2023-04-24
|
10
21
|
|
11
22
|
### Added
|
data/Gemfile
CHANGED
@@ -10,13 +10,13 @@ gem 'minitest', '~> 5.14' # For test
|
|
10
10
|
gem 'railties', require: false # For Rails integration testing
|
11
11
|
gem 'rake', '~> 13.0' # For test and automation
|
12
12
|
gem 'rubocop', '>= 0.79.0', require: false # For lint
|
13
|
+
gem 'rubocop-gem_dev', '>= 0.3.0', require: false # For lint
|
13
14
|
gem 'rubocop-md', '~> 1.0', require: false # For lint
|
14
15
|
gem 'rubocop-minitest', '>= 0.25.0', require: false # For lint
|
15
16
|
gem 'rubocop-performance', '>= 1.15.0', require: false # For lint
|
16
17
|
gem 'rubocop-rake', '>= 0.5.1', require: false # For lint
|
17
|
-
gem 'rubocop-sensible', '~> 0.3.0', require: false # For lint
|
18
18
|
gem 'ruby-lsp', require: false # For language server
|
19
|
-
gem 'simplecov', '~> 0.
|
19
|
+
gem 'simplecov', '~> 0.22.0', require: false # For test coverage
|
20
20
|
gem 'simplecov-cobertura', require: false # For test coverage
|
21
21
|
# gem 'steep', require: false # For language server and typing
|
22
22
|
# gem 'typeprof', require: false # For language server and typing
|
data/README.md
CHANGED
@@ -11,6 +11,40 @@
|
|
11
11
|
|
12
12
|
Alba is a JSON serializer for Ruby, JRuby, and TruffleRuby.
|
13
13
|
|
14
|
+
## TL;DR
|
15
|
+
|
16
|
+
Alba allows you to do something like below.
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
class User
|
20
|
+
attr_accessor :id, :name, :email
|
21
|
+
|
22
|
+
def initialize(id, name, email)
|
23
|
+
@id = id
|
24
|
+
@name = name
|
25
|
+
@email = email
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class UserResource
|
30
|
+
include Alba::Resource
|
31
|
+
|
32
|
+
root_key :user
|
33
|
+
|
34
|
+
attributes :id, :name
|
35
|
+
|
36
|
+
attribute :name_with_email do |resource|
|
37
|
+
"#{resource.name}: #{resource.email}"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com')
|
42
|
+
UserResource.new(user).serialize
|
43
|
+
# => '{"user":{"id":1,"name":"Masafumi OKURA","name_with_email":"Masafumi OKURA: masafumi@example.com"}}'
|
44
|
+
```
|
45
|
+
|
46
|
+
Seems useful? Continue reading!
|
47
|
+
|
14
48
|
## Discussions
|
15
49
|
|
16
50
|
Alba uses [GitHub Discussions](https://github.com/okuramasafumi/alba/discussions) to openly discuss the project.
|
@@ -82,7 +116,7 @@ You can find the documentation on [RubyDoc](https://rubydoc.info/github/okuramas
|
|
82
116
|
* Error handling
|
83
117
|
* Nil handling
|
84
118
|
* Circular associations control
|
85
|
-
*
|
119
|
+
* Types for validation and conversion
|
86
120
|
* Layout
|
87
121
|
* No runtime dependencies
|
88
122
|
|
@@ -235,6 +269,72 @@ class UserResource
|
|
235
269
|
end
|
236
270
|
```
|
237
271
|
|
272
|
+
#### Prefer methods on resource
|
273
|
+
|
274
|
+
By default, Alba prefers methods on the object to methods on the resource. This means if you have a following situation:
|
275
|
+
|
276
|
+
```ruby
|
277
|
+
class User
|
278
|
+
attr_accessor :id, :name, :email
|
279
|
+
|
280
|
+
def initialize(id, name, email)
|
281
|
+
@id = id
|
282
|
+
@name = name
|
283
|
+
@email = email
|
284
|
+
end
|
285
|
+
|
286
|
+
def name_with_email
|
287
|
+
"dummy!"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
class UserResource
|
292
|
+
include Alba::Resource
|
293
|
+
|
294
|
+
root_key :user, :users # Later is for plural
|
295
|
+
|
296
|
+
attributes :id, :name, :name_with_email
|
297
|
+
|
298
|
+
# Same method exists in `User` class!
|
299
|
+
# This is not called
|
300
|
+
def name_with_email(user)
|
301
|
+
"#{user.name}: #{user.email}"
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com')
|
306
|
+
UserResource.new(user).serialize
|
307
|
+
# => '{"user":{"id":1,"name":"Masafumi OKURA","name_with_email":"dummy!"}}'
|
308
|
+
```
|
309
|
+
|
310
|
+
You can see that `name_with_email` is now `dummy!` from `User#name_with_email`. You cna change this behavior by using `prefer_resource_method!` DSL in a resource class:
|
311
|
+
|
312
|
+
```ruby
|
313
|
+
# With the same `User` class
|
314
|
+
|
315
|
+
class UserResource
|
316
|
+
include Alba::Resource
|
317
|
+
|
318
|
+
prefer_resource_method! # This line is important
|
319
|
+
|
320
|
+
root_key :user, :users # Later is for plural
|
321
|
+
|
322
|
+
attributes :id, :name, :name_with_email
|
323
|
+
|
324
|
+
# Same method exists in `User` class!
|
325
|
+
# But now this is called!
|
326
|
+
def name_with_email(user)
|
327
|
+
"#{user.name}: #{user.email}"
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
user = User.new(1, 'Masafumi OKURA', 'masafumi@example.com')
|
332
|
+
UserResource.new(user).serialize
|
333
|
+
# => '{"user":{"id":1,"name":"Masafumi OKURA","name_with_email":"Masafumi OKURA: masafumi@example.com"}}'
|
334
|
+
```
|
335
|
+
|
336
|
+
The next major version of Alba will change this default behavior to prefer resource methods. In case you want to preserve current behavior, there's `prefer_object_method!` DSL, which does that.
|
337
|
+
|
238
338
|
#### Params
|
239
339
|
|
240
340
|
You can pass a Hash to the resource for internal use. It can be used as "flags" to control attribute content.
|
@@ -1070,6 +1170,11 @@ UserResource.new(User.new(1)).serialize
|
|
1070
1170
|
# => '{"user":{"id":1,"name":"User1","age":20}}'
|
1071
1171
|
```
|
1072
1172
|
|
1173
|
+
Note that `on_nil` does NOT work when the given object itself is `nil`. There are a few possible ways to deal with `nil`.
|
1174
|
+
|
1175
|
+
- Use `if` statement and avoid using Alba when the object is `nil`
|
1176
|
+
- Use "Null Object" pattern
|
1177
|
+
|
1073
1178
|
### Metadata
|
1074
1179
|
|
1075
1180
|
You can set a metadata with `meta` DSL or `meta` option.
|
@@ -1233,12 +1338,12 @@ In case you don't want to have a file for layout, Alba lets you define and apply
|
|
1233
1338
|
```ruby
|
1234
1339
|
class FooResource
|
1235
1340
|
include Alba::Resource
|
1236
|
-
layout inline: proc
|
1341
|
+
layout inline: proc {
|
1237
1342
|
{
|
1238
1343
|
header: 'my header',
|
1239
1344
|
body: serializable_hash
|
1240
1345
|
}
|
1241
|
-
|
1346
|
+
}
|
1242
1347
|
end
|
1243
1348
|
```
|
1244
1349
|
|
@@ -1249,12 +1354,12 @@ You can also use a Proc which returns String, not a Hash, for an inline layout.
|
|
1249
1354
|
```ruby
|
1250
1355
|
class FooResource
|
1251
1356
|
include Alba::Resource
|
1252
|
-
layout inline: proc
|
1357
|
+
layout inline: proc {
|
1253
1358
|
%({
|
1254
1359
|
"header": "my header",
|
1255
1360
|
"body": #{serialized_json}
|
1256
1361
|
})
|
1257
|
-
|
1362
|
+
}
|
1258
1363
|
end
|
1259
1364
|
```
|
1260
1365
|
|
@@ -1262,6 +1367,49 @@ It looks similar to file layout but you must use string interpolation for method
|
|
1262
1367
|
|
1263
1368
|
Also note that we use percentage notation here to use double quotes. Using single quotes in inline string layout causes the error which might be resolved in other ways.
|
1264
1369
|
|
1370
|
+
### Helper
|
1371
|
+
|
1372
|
+
Inheritance works well in most of the cases to share behaviors. One of the exceptions is when you want to shared behaviors with inline association. For example:
|
1373
|
+
|
1374
|
+
```ruby
|
1375
|
+
class ApplicationResource
|
1376
|
+
include Alba::Resource
|
1377
|
+
|
1378
|
+
def self.with_id
|
1379
|
+
attributes :id
|
1380
|
+
end
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
class LibraryResource < ApplicationResource
|
1384
|
+
with_id
|
1385
|
+
attributes :created_at
|
1386
|
+
|
1387
|
+
with_many :library_books do
|
1388
|
+
with_id # This DOES NOT work!
|
1389
|
+
attributes :created_at
|
1390
|
+
end
|
1391
|
+
end
|
1392
|
+
```
|
1393
|
+
|
1394
|
+
This doesn't work. Technically, inside of `has_many` is a separate class which doesn't inherit from the base class (`LibraryResource` in this example).
|
1395
|
+
|
1396
|
+
`helper` solves this problem. It's just a mark for methods that should be shared with inline associations.
|
1397
|
+
|
1398
|
+
```ruby
|
1399
|
+
class ApplicationResource
|
1400
|
+
include Alba::Resource
|
1401
|
+
|
1402
|
+
helper do
|
1403
|
+
def with_id
|
1404
|
+
attributes :id
|
1405
|
+
end
|
1406
|
+
end
|
1407
|
+
end
|
1408
|
+
# Now `LibraryResource` works!
|
1409
|
+
```
|
1410
|
+
|
1411
|
+
Within `helper` block, all methods should be defined without `self.`.
|
1412
|
+
|
1265
1413
|
### Caching
|
1266
1414
|
|
1267
1415
|
Currently, Alba doesn't support caching, primarily due to the behavior of `ActiveRecord::Relation`'s cache. See [the issue](https://github.com/rails/rails/issues/41784).
|
data/alba.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
|
|
13
13
|
spec.required_ruby_version = Gem::Requirement.new('>= 2.7.0')
|
14
14
|
|
15
15
|
spec.metadata = {
|
16
|
-
'bug_tracker_uri' => 'https://github.com/okuramasafumi/issues',
|
16
|
+
'bug_tracker_uri' => 'https://github.com/okuramasafumi/alba/issues',
|
17
17
|
'changelog_uri' => 'https://github.com/okuramasafumi/alba/blob/main/CHANGELOG.md',
|
18
18
|
'documentation_uri' => 'https://rubydoc.info/github/okuramasafumi/alba',
|
19
19
|
'source_code_uri' => 'https://github.com/okuramasafumi/alba',
|
data/lib/alba/association.rb
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
module Alba
|
2
2
|
# Representing association
|
3
|
+
# @api private
|
3
4
|
class Association
|
4
5
|
@const_cache = {}
|
5
6
|
class << self
|
7
|
+
# cache for `const_get`
|
6
8
|
attr_reader :const_cache
|
7
9
|
end
|
8
10
|
|
@@ -14,15 +16,16 @@ module Alba
|
|
14
16
|
# @param params [Hash] params override for the association
|
15
17
|
# @param nesting [String] a namespace where source class is inferred with
|
16
18
|
# @param key_transformation [Symbol] key transformation type
|
19
|
+
# @param helper [Module] helper module to include
|
17
20
|
# @param block [Block] used to define resource when resource arg is absent
|
18
|
-
def initialize(name:, condition: nil, resource: nil, params: {}, nesting: nil, key_transformation: :none, &block)
|
21
|
+
def initialize(name:, condition: nil, resource: nil, params: {}, nesting: nil, key_transformation: :none, helper: nil, &block)
|
19
22
|
@name = name
|
20
23
|
@condition = condition
|
21
24
|
@resource = resource
|
22
25
|
@params = params
|
23
26
|
return if @resource
|
24
27
|
|
25
|
-
assign_resource(nesting, key_transformation, block)
|
28
|
+
assign_resource(nesting, key_transformation, block, helper)
|
26
29
|
end
|
27
30
|
|
28
31
|
# Recursively converts an object into a Hash
|
@@ -59,9 +62,10 @@ module Alba
|
|
59
62
|
end
|
60
63
|
end
|
61
64
|
|
62
|
-
def assign_resource(nesting, key_transformation, block)
|
65
|
+
def assign_resource(nesting, key_transformation, block, helper) # rubocop:disable Metrics/MethodLength
|
63
66
|
@resource = if block
|
64
67
|
klass = Alba.resource_class
|
68
|
+
klass.helper(helper) if helper
|
65
69
|
klass.transform_keys(key_transformation)
|
66
70
|
klass.class_eval(&block)
|
67
71
|
klass
|
@@ -3,6 +3,7 @@ require_relative 'constants'
|
|
3
3
|
|
4
4
|
module Alba
|
5
5
|
# Represents attribute with `if` option
|
6
|
+
# @api private
|
6
7
|
class ConditionalAttribute
|
7
8
|
# @param body [Symbol, Proc, Alba::Association, Alba::TypedAttribute] real attribute wrapped with condition
|
8
9
|
# @param condition [Symbol, Proc] condition to check
|
@@ -2,7 +2,7 @@ begin
|
|
2
2
|
require 'active_support/inflector'
|
3
3
|
require 'active_support/core_ext/module/delegation'
|
4
4
|
rescue LoadError
|
5
|
-
raise
|
5
|
+
raise Alba::Error, 'To use default inflector, please install `ActiveSupport` gem.'
|
6
6
|
end
|
7
7
|
|
8
8
|
module Alba
|
@@ -11,6 +11,18 @@ module Alba
|
|
11
11
|
# Another is that `ActiveSupport::Inflector` doesn't have `camelize_lower` method that we want it to have, so this module works as an adapter.
|
12
12
|
module DefaultInflector
|
13
13
|
class << self
|
14
|
+
# @!method camelize(key)
|
15
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-camelize ActiveSupport::Inflector#camelize
|
16
|
+
# @!method dasherize(key)
|
17
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-dasherize ActiveSupport::Inflector#dasherize
|
18
|
+
# @!method underscore(key)
|
19
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-underscore ActiveSupport::Inflector#underscore
|
20
|
+
# @!method classify(key)
|
21
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-classify ActiveSupport::Inflector#classify
|
22
|
+
# @!method demodulize(key)
|
23
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-demodulize ActiveSupport::Inflector#demodulize
|
24
|
+
# @!method pluralize(key)
|
25
|
+
# @see https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-pluralize ActiveSupport::Inflector#pluralize
|
14
26
|
delegate :camelize, :dasherize, :underscore, :classify, :demodulize, :pluralize, to: ActiveSupport::Inflector
|
15
27
|
end
|
16
28
|
|
data/lib/alba/deprecation.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module Alba
|
2
2
|
# Module for printing deprecation warning
|
3
|
+
# @api private
|
3
4
|
module Deprecation
|
4
|
-
# Similar to {
|
5
|
+
# Similar to {#warn} but prints caller as well
|
5
6
|
#
|
6
7
|
# @param message [String] main message to print
|
7
8
|
# @return void
|
data/lib/alba/layout.rb
CHANGED
data/lib/alba/resource.rb
CHANGED
@@ -11,7 +11,7 @@ module Alba
|
|
11
11
|
module Resource
|
12
12
|
# @!parse include InstanceMethods
|
13
13
|
# @!parse extend ClassMethods
|
14
|
-
DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _key_transformation_cascade: true, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil}.freeze # rubocop:disable Layout/LineLength
|
14
|
+
DSLS = {_attributes: {}, _key: nil, _key_for_collection: nil, _meta: nil, _transform_type: :none, _transforming_root_key: false, _key_transformation_cascade: true, _on_error: nil, _on_nil: nil, _layout: nil, _collection_key: nil, _helper: nil}.freeze # rubocop:disable Layout/LineLength
|
15
15
|
private_constant :DSLS
|
16
16
|
|
17
17
|
WITHIN_DEFAULT = Object.new.freeze
|
@@ -80,7 +80,7 @@ module Alba
|
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
83
|
-
# Returns a Hash correspondng {
|
83
|
+
# Returns a Hash correspondng {#serialize}
|
84
84
|
#
|
85
85
|
# @param root_key [Symbol, nil, true]
|
86
86
|
# @param meta [Hash] metadata for this seialization
|
@@ -260,18 +260,28 @@ module Alba
|
|
260
260
|
when TypedAttribute then attribute.value(obj)
|
261
261
|
when NestedAttribute then attribute.value(object: obj, params: params)
|
262
262
|
when ConditionalAttribute then attribute.with_passing_condition(resource: self, object: obj) { |attr| fetch_attribute(obj, key, attr) }
|
263
|
-
else
|
264
|
-
raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
|
263
|
+
else raise ::Alba::Error, "Unsupported type of attribute: #{attribute.class}"
|
265
264
|
end
|
266
265
|
value.nil? && nil_handler ? instance_exec(obj, key, attribute, &nil_handler) : value
|
267
266
|
end
|
268
267
|
|
268
|
+
# TODO: from version 3, `_fetch_attribute_from_resource_first` is default
|
269
269
|
def fetch_attribute_from_object_and_resource(obj, attribute)
|
270
|
+
_fetch_attribute_from_object_first(obj, attribute)
|
271
|
+
end
|
272
|
+
|
273
|
+
def _fetch_attribute_from_object_first(obj, attribute)
|
270
274
|
obj.__send__(attribute)
|
271
275
|
rescue NoMethodError
|
272
276
|
__send__(attribute, obj)
|
273
277
|
end
|
274
278
|
|
279
|
+
def _fetch_attribute_from_resource_first(obj, attribute)
|
280
|
+
__send__(attribute, obj)
|
281
|
+
rescue NoMethodError
|
282
|
+
obj.__send__(attribute)
|
283
|
+
end
|
284
|
+
|
275
285
|
def nil_handler
|
276
286
|
@_on_nil
|
277
287
|
end
|
@@ -374,8 +384,7 @@ module Alba
|
|
374
384
|
def association(name, condition = nil, resource: nil, key: nil, params: {}, **options, &block)
|
375
385
|
key_transformation = @_key_transformation_cascade ? @_transform_type : :none
|
376
386
|
assoc = Association.new(
|
377
|
-
name: name, condition: condition, resource: resource, params: params, nesting: nesting, key_transformation: key_transformation,
|
378
|
-
&block
|
387
|
+
name: name, condition: condition, resource: resource, params: params, nesting: nesting, key_transformation: key_transformation, helper: @_helper, &block
|
379
388
|
)
|
380
389
|
@_attributes[key&.to_sym || name.to_sym] = options[:if] ? ConditionalAttribute.new(body: assoc, condition: options[:if]) : assoc
|
381
390
|
end
|
@@ -388,7 +397,7 @@ module Alba
|
|
388
397
|
if name.nil?
|
389
398
|
nil
|
390
399
|
else
|
391
|
-
name.rpartition('::').first.
|
400
|
+
name.rpartition('::').first.then { |n| n.empty? ? nil : n }
|
392
401
|
end
|
393
402
|
end
|
394
403
|
private :nesting
|
@@ -503,6 +512,25 @@ module Alba
|
|
503
512
|
def on_nil(&block)
|
504
513
|
@_on_nil = block
|
505
514
|
end
|
515
|
+
|
516
|
+
# Define helper methods
|
517
|
+
#
|
518
|
+
# @param mod [Module] a module to extend
|
519
|
+
def helper(mod = @_helper || Module.new, &block)
|
520
|
+
mod.module_eval(&block) if block
|
521
|
+
extend mod
|
522
|
+
@_helper = mod
|
523
|
+
end
|
524
|
+
|
525
|
+
# DSL for alias, purely for readability
|
526
|
+
def prefer_resource_method!
|
527
|
+
alias_method :fetch_attribute_from_object_and_resource, :_fetch_attribute_from_resource_first
|
528
|
+
end
|
529
|
+
|
530
|
+
# DSL for alias, purely for readability
|
531
|
+
def prefer_object_method!
|
532
|
+
alias_method :fetch_attribute_from_object_and_resource, :_fetch_attribute_from_object_first
|
533
|
+
end
|
506
534
|
end
|
507
535
|
end
|
508
536
|
end
|
data/lib/alba/typed_attribute.rb
CHANGED
data/lib/alba/version.rb
CHANGED
data/lib/alba.rb
CHANGED
@@ -66,7 +66,7 @@ module Alba
|
|
66
66
|
# @param with [Symbol, Class, Module] inflector
|
67
67
|
# When it's a Symbol, it sets inflector with given name
|
68
68
|
# When it's a Class or a Module, it sets given object to inflector
|
69
|
-
# @deprecated Use {
|
69
|
+
# @deprecated Use {.inflector=} instead
|
70
70
|
def enable_inference!(with:)
|
71
71
|
Alba::Deprecation.warn('Alba.enable_inference! is deprecated. Use `Alba.inflector=` instead.')
|
72
72
|
@inflector = inflector_from(with)
|
@@ -75,14 +75,14 @@ module Alba
|
|
75
75
|
|
76
76
|
# Disable inference for key and resource name
|
77
77
|
#
|
78
|
-
# @deprecated Use {
|
78
|
+
# @deprecated Use {.inflector=} instead
|
79
79
|
def disable_inference!
|
80
80
|
Alba::Deprecation.warn('Alba.disable_inference! is deprecated. Use `Alba.inflector = nil` instead.')
|
81
81
|
@inferring = false
|
82
82
|
@inflector = nil
|
83
83
|
end
|
84
84
|
|
85
|
-
# @deprecated Use {
|
85
|
+
# @deprecated Use {.inflector} instead
|
86
86
|
# @return [Boolean] whether inference is enabled or not
|
87
87
|
def inferring
|
88
88
|
Alba::Deprecation.warn('Alba.inferring is deprecated. Use `Alba.inflector` instead.')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alba
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OKURA Masafumi
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-01 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Alba is the fastest JSON serializer for Ruby. It focuses on performance,
|
14
14
|
flexibility and usability.
|
@@ -19,6 +19,7 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- ".codeclimate.yml"
|
22
|
+
- ".editorconfig"
|
22
23
|
- ".github/ISSUE_TEMPLATE/bug_report.md"
|
23
24
|
- ".github/ISSUE_TEMPLATE/feature_request.md"
|
24
25
|
- ".github/dependabot.yml"
|
@@ -71,7 +72,7 @@ homepage: https://github.com/okuramasafumi/alba
|
|
71
72
|
licenses:
|
72
73
|
- MIT
|
73
74
|
metadata:
|
74
|
-
bug_tracker_uri: https://github.com/okuramasafumi/issues
|
75
|
+
bug_tracker_uri: https://github.com/okuramasafumi/alba/issues
|
75
76
|
changelog_uri: https://github.com/okuramasafumi/alba/blob/main/CHANGELOG.md
|
76
77
|
documentation_uri: https://rubydoc.info/github/okuramasafumi/alba
|
77
78
|
source_code_uri: https://github.com/okuramasafumi/alba
|
@@ -91,7 +92,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
92
|
- !ruby/object:Gem::Version
|
92
93
|
version: '0'
|
93
94
|
requirements: []
|
94
|
-
rubygems_version: 3.4.
|
95
|
+
rubygems_version: 3.4.14
|
95
96
|
signing_key:
|
96
97
|
specification_version: 4
|
97
98
|
summary: Alba is the fastest JSON serializer for Ruby.
|