alba 3.8.0 → 3.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 +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +44 -14
- data/lib/alba/association.rb +19 -2
- data/lib/alba/conditional_attribute.rb +3 -3
- data/lib/alba/resource.rb +3 -2
- data/lib/alba/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9f883beafbee55bdfc1bb9b55e821c6df5b167e5311cbeced743ae7c60de5657
|
4
|
+
data.tar.gz: e9c031cd63e51f160f1ec1f1b42ac8676b0ff172ff2438f549ab83d38d848817
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73b22da7dc5d360297838b326c3f130e18027b9fc203e3bdec48c13f80f4105a5fa019304a947dbc85aea40ee94e796cb20ba4c7c51f9a8c3cc02d29336f80f9
|
7
|
+
data.tar.gz: 2d82dfd6188126db9726982440465e9bc4cf6165e2eaf2c51f0d729eee1e8fa2d2c54b5d8aafce710979ba67be437f4bc152dc1e91352cea421925b32068c73f
|
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
|
+
## 3.9.0 2025-08-14
|
10
|
+
|
11
|
+
### Added
|
12
|
+
|
13
|
+
- Add source option to associations [#459](https://github.com/okuramasafumi/alba/pull/459)
|
14
|
+
- Thank you, @skryukov
|
15
|
+
|
16
|
+
### Fixed
|
17
|
+
|
18
|
+
- `params` isn't available in `attribute` with two-arity condition [#456](https://github.com/okuramasafumi/alba/issues/456)
|
19
|
+
|
9
20
|
## 3.8.0 2025-08-02
|
10
21
|
|
11
22
|
### Added
|
data/README.md
CHANGED
@@ -617,6 +617,34 @@ FooResource.new(foo, params: {expose_secret: true}).serialize # => '{"foo":{"bar
|
|
617
617
|
FooResourceWithParamsOverride.new(foo, params: {expose_secret: true}).serialize # => '{"foo":{"bar":{"baz":{"data":1}}}}'
|
618
618
|
```
|
619
619
|
|
620
|
+
#### Custom association source
|
621
|
+
|
622
|
+
You can specify a custom source for associations using the `source` option with a proc. The `source` proc is executed in the context of the target object and can receive `params` for dynamic behavior. This allows you to retrieve association data from methods other than the association name or access instance variables.
|
623
|
+
|
624
|
+
```ruby
|
625
|
+
class User
|
626
|
+
attr_accessor :id, :name, :metadata
|
627
|
+
|
628
|
+
def custom_profile
|
629
|
+
{profile: {email: "#{name.downcase}@example.com"}}
|
630
|
+
end
|
631
|
+
end
|
632
|
+
|
633
|
+
class UserResource
|
634
|
+
include Alba::Resource
|
635
|
+
|
636
|
+
attributes :id, :name
|
637
|
+
|
638
|
+
# Use a custom method as source
|
639
|
+
one :profile, source: proc { custom_profile[:profile] }
|
640
|
+
|
641
|
+
# Access instance variables
|
642
|
+
one :user_metadata, source: proc { @metadata }
|
643
|
+
end
|
644
|
+
```
|
645
|
+
|
646
|
+
|
647
|
+
|
620
648
|
### Nested Attribute
|
621
649
|
|
622
650
|
Alba supports nested attributes that makes it easy to build complex data structure from single object.
|
@@ -778,15 +806,15 @@ Alba.serialize(
|
|
778
806
|
[foo1, bar1, foo2, bar2],
|
779
807
|
# `with` option takes a lambda to return resource class
|
780
808
|
with: lambda do |obj|
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
809
|
+
case obj
|
810
|
+
when Foo
|
811
|
+
CustomFooResource
|
812
|
+
when Bar
|
813
|
+
BarResource
|
814
|
+
else
|
815
|
+
raise # Impossible in this case
|
816
|
+
end
|
817
|
+
end
|
790
818
|
)
|
791
819
|
# => '[{"id":1},{"id":1,"address":"bar1"},{"id":2},{"id":2,"address":"bar2"}]'
|
792
820
|
# Note `CustomFooResource` is used here
|
@@ -1225,7 +1253,7 @@ There are four possible arguments `on_error` method accepts.
|
|
1225
1253
|
* `:nullify` sets the attribute with the error to `nil`.
|
1226
1254
|
* Block gives you more control over what to be returned.
|
1227
1255
|
|
1228
|
-
The block receives five arguments, `error`, `object`, `key`, `attribute` and `resource class` and must return a two-element array. Below is an example.
|
1256
|
+
The block receives five arguments, `error`, `object`, `key`, `attribute` and `resource class` and must return a two-element array. You can also ignore the given key with returning `Alba::REMOVE_KEY`, so that you can get even finer control over errors. Below is an example.
|
1229
1257
|
|
1230
1258
|
```ruby
|
1231
1259
|
class ExampleResource
|
@@ -1235,12 +1263,14 @@ class ExampleResource
|
|
1235
1263
|
if resource_class == MyResource
|
1236
1264
|
['error_fallback', object.error_fallback]
|
1237
1265
|
else
|
1238
|
-
|
1266
|
+
Alba::REMOVE_KEY
|
1239
1267
|
end
|
1240
1268
|
end
|
1241
1269
|
end
|
1242
1270
|
```
|
1243
1271
|
|
1272
|
+
For more information, consult to [test code](https://github.com/okuramasafumi/alba/blob/main/test/usecases/on_error_test.rb).
|
1273
|
+
|
1244
1274
|
### Nil handling
|
1245
1275
|
|
1246
1276
|
Sometimes we want to convert `nil` to different values such as empty string. Alba provides a flexible way to handle `nil`.
|
@@ -1520,8 +1550,8 @@ Alba supports serializing JSON in a layout. You need a file for layout and then
|
|
1520
1550
|
|
1521
1551
|
```erb
|
1522
1552
|
{
|
1523
|
-
|
1524
|
-
|
1553
|
+
"header": "my_header",
|
1554
|
+
"body": <%= serialized_json %>
|
1525
1555
|
}
|
1526
1556
|
```
|
1527
1557
|
|
@@ -1909,7 +1939,7 @@ AuthorResource.new(
|
|
1909
1939
|
author,
|
1910
1940
|
params: {
|
1911
1941
|
index: author.books.map.with_index { |book, index| [book.id, index] }
|
1912
|
-
|
1942
|
+
.to_h
|
1913
1943
|
}
|
1914
1944
|
).serialize
|
1915
1945
|
# => {"id":2,"books":[{"id":2,"name":"book2","index":0},{"id":3,"name":"book3","index":1},{"id":1,"name":"book1","index":2}]}
|
data/lib/alba/association.rb
CHANGED
@@ -16,16 +16,29 @@ module Alba
|
|
16
16
|
# @param condition [Proc, nil] a proc filtering data
|
17
17
|
# @param resource [Class<Alba::Resource>, Proc, String, Symbol, nil]
|
18
18
|
# a resource class for the association, a proc returning a resource class or a name of the resource
|
19
|
+
# @param source [Proc, nil] a proc to specify the source of the association
|
19
20
|
# @param with_traits [Symbol, Array<Symbol>, nil] specified traits
|
20
21
|
# @param params [Hash] params override for the association
|
21
22
|
# @param nesting [String] a namespace where source class is inferred with
|
22
23
|
# @param key_transformation [Symbol] key transformation type
|
23
24
|
# @param helper [Module] helper module to include
|
24
25
|
# @param block [Block] used to define resource when resource arg is absent
|
25
|
-
def initialize(
|
26
|
+
def initialize(
|
27
|
+
name:,
|
28
|
+
condition: nil,
|
29
|
+
resource: nil,
|
30
|
+
source: nil,
|
31
|
+
with_traits: nil,
|
32
|
+
params: {},
|
33
|
+
nesting: nil,
|
34
|
+
key_transformation: :none,
|
35
|
+
helper: nil,
|
36
|
+
&block
|
37
|
+
)
|
26
38
|
@name = name
|
27
39
|
@condition = condition
|
28
40
|
@resource = resource
|
41
|
+
@source = source
|
29
42
|
@with_traits = with_traits
|
30
43
|
@params = params
|
31
44
|
return if @resource
|
@@ -64,7 +77,11 @@ module Alba
|
|
64
77
|
private
|
65
78
|
|
66
79
|
def object_from(target, params)
|
67
|
-
o =
|
80
|
+
o = if @source
|
81
|
+
target.instance_exec(params, &@source)
|
82
|
+
else
|
83
|
+
target.is_a?(Hash) ? target.fetch(@name) : target.__send__(@name)
|
84
|
+
end
|
68
85
|
o = @condition.call(o, params, target) if @condition
|
69
86
|
o
|
70
87
|
end
|
@@ -25,7 +25,7 @@ module Alba
|
|
25
25
|
fetched_attribute = yield(@body)
|
26
26
|
return fetched_attribute unless with_two_arity_proc_condition?
|
27
27
|
|
28
|
-
return Alba::REMOVE_KEY unless resource.instance_exec(object, second_object(object), &@condition)
|
28
|
+
return Alba::REMOVE_KEY unless resource.instance_exec(object, second_object(object, resource), &@condition)
|
29
29
|
|
30
30
|
fetched_attribute
|
31
31
|
end
|
@@ -50,14 +50,14 @@ module Alba
|
|
50
50
|
@condition.is_a?(Proc) && @condition.arity >= 2
|
51
51
|
end
|
52
52
|
|
53
|
-
def second_object(object)
|
53
|
+
def second_object(object, resource)
|
54
54
|
case @body
|
55
55
|
when Symbol, Alba::Association, Alba::TypedAttribute
|
56
56
|
object.__send__(@body.name)
|
57
57
|
when Alba::NestedAttribute
|
58
58
|
nil
|
59
59
|
when Proc
|
60
|
-
|
60
|
+
resource.instance_exec(object, &@body)
|
61
61
|
else raise Alba::Error, "Unreachable code, @body is: #{@body.inspect}"
|
62
62
|
end
|
63
63
|
end
|
data/lib/alba/resource.rb
CHANGED
@@ -429,6 +429,7 @@ module Alba
|
|
429
429
|
# @param condition [Proc, nil] a Proc to modify the association
|
430
430
|
# @param resource [Class<Alba::Resource>, String, Proc, nil] representing resource for this association
|
431
431
|
# @param serializer [Class<Alba::Resource>, String, Proc, nil] alias for `resource`
|
432
|
+
# @param source [Proc, nil] a Proc to customize the association source
|
432
433
|
# @param key [String, Symbol, nil] used as key when given
|
433
434
|
# @param with_traits [Symbol, Array<Symbol>, nil] specified traits
|
434
435
|
# @param params [Hash] params override for the association
|
@@ -437,11 +438,11 @@ module Alba
|
|
437
438
|
# @param block [Block]
|
438
439
|
# @return [void]
|
439
440
|
# @see Alba::Association#initialize
|
440
|
-
def association(name, condition = nil, resource: nil, serializer: nil, key: nil, with_traits: nil, params: {}, **options, &block)
|
441
|
+
def association(name, condition = nil, resource: nil, serializer: nil, source: nil, key: nil, with_traits: nil, params: {}, **options, &block)
|
441
442
|
resource ||= serializer
|
442
443
|
transformation = @_key_transformation_cascade ? @_transform_type : :none
|
443
444
|
assoc = Association.new(
|
444
|
-
name: name, condition: condition, resource: resource, with_traits: with_traits,
|
445
|
+
name: name, condition: condition, resource: resource, source: source, with_traits: with_traits,
|
445
446
|
params: params, nesting: nesting, key_transformation: transformation, helper: @_helper,
|
446
447
|
&block
|
447
448
|
)
|
data/lib/alba/version.rb
CHANGED