graphiti 2.0.0.beta.1 → 2.0.0.beta.3
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/.ruby-version +1 -0
- data/.tool-versions +1 -0
- data/CHANGELOG.md +23 -0
- data/UPGRADING.md +0 -10
- data/lib/graphiti/errors.rb +13 -19
- data/lib/graphiti/resource/interface.rb +20 -0
- data/lib/graphiti/resource/persistence.rb +14 -2
- data/lib/graphiti/resource_proxy.rb +6 -0
- data/lib/graphiti/util/persistence.rb +10 -11
- data/lib/graphiti/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 69a8294c01d96b3ca136060036e2b8592f46464a775965f6f2e42129915854bd
|
|
4
|
+
data.tar.gz: e133c0cf444718997a718e16a957b6e11d86aec78696ac2cd4bb4fe8e3b907eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fb38ebe38f207b016b61a960f0b39890fe4cb3aa8e8bc70a50f5f82894513c9360fe37ce02de50a7de14718d5a0f5865a50d6defe1ce15e2730409bc3324401c
|
|
7
|
+
data.tar.gz: cc5090ad354c15c4f7d5a2c9daa8aab78be9bc7b4f41c62569a5fa5edf7496dd79e2b0d86533027fd7989ed1f7295950fc325a1cf9475ae03992ddd6344a2e27
|
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.3
|
data/.tool-versions
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby 3.3.4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
graphiti changelog
|
|
2
2
|
|
|
3
|
+
# [2.0.0-beta.3](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.2...v2.0.0-beta.3) (2026-07-31)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* carry the assigned model on the resource, not through override signatures ([8ad848d](https://github.com/graphiti-api/graphiti/commit/8ad848d9bcd24cd63efb67e8ce32d5c8f3cfe147))
|
|
9
|
+
|
|
10
|
+
# [2.0.0-beta.2](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.1...v2.0.0-beta.2) (2026-07-30)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* add Resource.wrap as an easy way to use graphiti serialization on models fetched via other means (and not via graphiti's finders) ([#513](https://github.com/graphiti-api/graphiti/issues/513)) ([fcd19e2](https://github.com/graphiti-api/graphiti/commit/fcd19e2d023091d85947dbdd89259b587e0f582b))
|
|
16
|
+
* deprecate mutating attributes in around_persistence hooks ([#514](https://github.com/graphiti-api/graphiti/issues/514)) [skip ci] ([8410ab0](https://github.com/graphiti-api/graphiti/commit/8410ab0a916077601cf85d8260a05ef9098149eb))
|
|
17
|
+
|
|
3
18
|
# [2.0.0-beta.1](https://github.com/graphiti-api/graphiti/compare/v1.12.2...v2.0.0-beta.1) (2026-07-30)
|
|
4
19
|
|
|
5
20
|
|
|
@@ -14,6 +29,14 @@ graphiti changelog
|
|
|
14
29
|
* around_persistence hooks receive the assigned model instead of the attributes hash. Move attribute-hash modifications to before_attributes, or set values on the model. Custom create/update overrides that should receive a pre-assigned model must accept an assigned_model: keyword. See UPGRADING.md
|
|
15
30
|
* Ruby >= 3.0 / Rails >= 6 are now required.
|
|
16
31
|
|
|
32
|
+
# [1.13.0](https://github.com/graphiti-api/graphiti/compare/v1.12.2...v1.13.0) (2026-07-30)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
### Features
|
|
36
|
+
|
|
37
|
+
* add Resource.wrap as an easy way to use graphiti serialization on models fetched via other means (and not via graphiti's finders) ([#513](https://github.com/graphiti-api/graphiti/issues/513)) ([fcd19e2](https://github.com/graphiti-api/graphiti/commit/fcd19e2d023091d85947dbdd89259b587e0f582b))
|
|
38
|
+
* deprecate mutating attributes in around_persistence hooks ([#514](https://github.com/graphiti-api/graphiti/issues/514)) [skip ci] ([8410ab0](https://github.com/graphiti-api/graphiti/commit/8410ab0a916077601cf85d8260a05ef9098149eb))
|
|
39
|
+
|
|
17
40
|
## [1.12.2](https://github.com/graphiti-api/graphiti/compare/v1.12.1...v1.12.2) (2026-07-29)
|
|
18
41
|
|
|
19
42
|
|
data/UPGRADING.md
CHANGED
|
@@ -54,16 +54,6 @@ To migrate, move attribute-hash modifications to `before_attributes` (which stil
|
|
|
54
54
|
|
|
55
55
|
`before/around/after_attributes` and `before/around/after_save` are unchanged.
|
|
56
56
|
|
|
57
|
-
### Breaking: custom create/update overrides and pre-assigned models
|
|
58
|
-
|
|
59
|
-
If a resource overrides `create` or `update` and callers inspect the model before saving, the override must accept the already-assigned model:
|
|
60
|
-
|
|
61
|
-
```ruby
|
|
62
|
-
def create(attributes, meta = nil, assigned_model: nil)
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Without the keyword, saving a proxy whose model was inspected raises `Graphiti::Errors::AssignedModelNotSupported` rather than silently discarding changes made to the inspected instance. Overridden resources used only via plain `save` are unaffected.
|
|
66
|
-
|
|
67
57
|
### Fine print
|
|
68
58
|
|
|
69
59
|
- If you inspect the model before saving, the attributes callbacks run at inspection time (in your controller, outside the save transaction). On the plain `save` path they run inside the transaction, at the same point as 1.x.
|
data/lib/graphiti/errors.rb
CHANGED
|
@@ -84,25 +84,6 @@ module Graphiti
|
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
87
|
-
class AssignedModelNotSupported < Base
|
|
88
|
-
def initialize(resource_class, method_name)
|
|
89
|
-
@resource_class = resource_class
|
|
90
|
-
@method_name = method_name
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def message
|
|
94
|
-
<<~MSG
|
|
95
|
-
#{@resource_class}: the model was already assigned via #assign_attributes (or #data before save), but ##{@method_name} is overridden without a parameter to receive it, so changes made to the unsaved model would be silently lost.
|
|
96
|
-
|
|
97
|
-
Accept and use the assigned model in your override:
|
|
98
|
-
|
|
99
|
-
def #{@method_name}(attributes, meta = nil, assigned_model: nil)
|
|
100
|
-
|
|
101
|
-
or persist with #save alone, without inspecting the model first. See UPGRADING.md.
|
|
102
|
-
MSG
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
87
|
class RemoteWrite < Base
|
|
107
88
|
def initialize(resource_class)
|
|
108
89
|
@resource_class = resource_class
|
|
@@ -486,6 +467,19 @@ module Graphiti
|
|
|
486
467
|
end
|
|
487
468
|
end
|
|
488
469
|
|
|
470
|
+
class InvalidWrapModel < Base
|
|
471
|
+
def initialize(resource_class, model)
|
|
472
|
+
@resource_class = resource_class
|
|
473
|
+
@model = model
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
def message
|
|
477
|
+
<<~MSG
|
|
478
|
+
#{@resource_class.name}.wrap was given a #{@model.class}, but this resource is for #{@resource_class.model} (subclasses are fine).
|
|
479
|
+
MSG
|
|
480
|
+
end
|
|
481
|
+
end
|
|
482
|
+
|
|
489
483
|
class ResourceEndpointConflict < Base
|
|
490
484
|
def initialize(path, action, resource_a, resource_b)
|
|
491
485
|
@path = path
|
|
@@ -53,8 +53,28 @@ module Graphiti
|
|
|
53
53
|
runner.proxy(base_scope, single: true, raise_on_missing: true, assign_action: :create)
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
# Wrap models fetched outside graphiti so they render like any other proxy
|
|
57
|
+
def wrap(models, base_scope = nil)
|
|
58
|
+
validate_wrap_models!(models)
|
|
59
|
+
runner = Runner.new(self, {}, nil, :find)
|
|
60
|
+
runner.proxy(base_scope, bypass_required_filters: true).tap do |proxy|
|
|
61
|
+
proxy.data = models
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
56
65
|
private
|
|
57
66
|
|
|
67
|
+
# Skip polymorphic parents - resource_for_model raises a better error for unknown children
|
|
68
|
+
def validate_wrap_models!(models)
|
|
69
|
+
return if abstract_class? || (polymorphic? && !polymorphic_child?)
|
|
70
|
+
|
|
71
|
+
[models].flatten.compact.each do |model|
|
|
72
|
+
unless model.is_a?(self.model)
|
|
73
|
+
raise Errors::InvalidWrapModel.new(self, model)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
58
78
|
def caching_options
|
|
59
79
|
{cache: @cache_resource, cache_expires_in: @cache_expires_in, cache_tag: @cache_tag}
|
|
60
80
|
end
|
|
@@ -93,11 +93,23 @@ module Graphiti
|
|
|
93
93
|
model_instance
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
# The model built by a prior ResourceProxy#assign_attributes, present
|
|
97
|
+
# for the duration of the save that persists it
|
|
98
|
+
attr_reader :assigned_model
|
|
99
|
+
|
|
100
|
+
# @api private
|
|
101
|
+
def with_assigned_model(model)
|
|
102
|
+
@assigned_model = model
|
|
103
|
+
yield
|
|
104
|
+
ensure
|
|
105
|
+
@assigned_model = nil
|
|
106
|
+
end
|
|
107
|
+
|
|
96
108
|
# Attributes are assigned before the persistence callbacks fire, so
|
|
97
109
|
# around_persistence receives the assigned model - its pre-yield
|
|
98
110
|
# position is the last chance to touch the model before save, inside
|
|
99
111
|
# the transaction. Modify attributes in before_attributes instead.
|
|
100
|
-
def create(create_params, meta = nil
|
|
112
|
+
def create(create_params, meta = nil)
|
|
101
113
|
model_instance = assigned_model || assign(create_params, meta, :create)
|
|
102
114
|
|
|
103
115
|
run_callbacks :persistence, :create, model_instance, meta do
|
|
@@ -111,7 +123,7 @@ module Graphiti
|
|
|
111
123
|
model_instance
|
|
112
124
|
end
|
|
113
125
|
|
|
114
|
-
def update(update_params, meta = nil
|
|
126
|
+
def update(update_params, meta = nil)
|
|
115
127
|
model_instance = assigned_model || assign(update_params, meta, :update)
|
|
116
128
|
|
|
117
129
|
run_callbacks :persistence, :update, model_instance, meta do
|
|
@@ -82,6 +82,12 @@ module Graphiti
|
|
|
82
82
|
Renderer.new(self, options).as_graphql
|
|
83
83
|
end
|
|
84
84
|
|
|
85
|
+
# Records supplied directly, no scope resolution
|
|
86
|
+
def data=(models)
|
|
87
|
+
@data = models
|
|
88
|
+
[@data].flatten.compact.each { |record| @resource.decorate_record(record) }
|
|
89
|
+
end
|
|
90
|
+
|
|
85
91
|
def data
|
|
86
92
|
return @data unless @data.nil?
|
|
87
93
|
return assign_attributes(@payload.params) if @assign_action
|
|
@@ -190,22 +190,21 @@ class Graphiti::Util::Persistence
|
|
|
190
190
|
}
|
|
191
191
|
end
|
|
192
192
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
# The assigned model rides on the resource instance rather than through
|
|
194
|
+
# the method signature, so any override of #create/#update - whatever its
|
|
195
|
+
# arity - passes it through untouched.
|
|
197
196
|
def call_resource_method(method_name, attributes, caller_model)
|
|
198
197
|
method = @resource.method(method_name)
|
|
198
|
+
call = if method.arity == 1
|
|
199
|
+
-> { method.call(attributes) }
|
|
200
|
+
else
|
|
201
|
+
-> { method.call(attributes, metadata) }
|
|
202
|
+
end
|
|
199
203
|
|
|
200
204
|
if @assigned_model && [:create, :update].include?(method_name)
|
|
201
|
-
|
|
202
|
-
raise Graphiti::Errors::AssignedModelNotSupported.new(@resource.class, method_name)
|
|
203
|
-
end
|
|
204
|
-
method.call(attributes, metadata, assigned_model: @assigned_model)
|
|
205
|
-
elsif method.arity == 1
|
|
206
|
-
method.call(attributes)
|
|
205
|
+
@resource.with_assigned_model(@assigned_model) { call.call }
|
|
207
206
|
else
|
|
208
|
-
|
|
207
|
+
call.call
|
|
209
208
|
end
|
|
210
209
|
end
|
|
211
210
|
end
|
data/lib/graphiti/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: graphiti
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.beta.
|
|
4
|
+
version: 2.0.0.beta.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Lee Richmond
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-31 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: jsonapi-serializable
|
|
@@ -237,7 +237,9 @@ files:
|
|
|
237
237
|
- ".github/workflows/release.yml"
|
|
238
238
|
- ".gitignore"
|
|
239
239
|
- ".rspec"
|
|
240
|
+
- ".ruby-version"
|
|
240
241
|
- ".standard.yml"
|
|
242
|
+
- ".tool-versions"
|
|
241
243
|
- ".yardopts"
|
|
242
244
|
- Appraisals
|
|
243
245
|
- CHANGELOG.md
|