graphiti 2.0.0.beta.6 → 2.0.0.beta.7
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 +9 -0
- data/docs/topics/testing.md +44 -22
- data/docs/upgrading.md +1 -0
- data/lib/generators/graphiti/install_generator.rb +0 -1
- data/lib/generators/graphiti/templates/index_request_spec.rb.erb +2 -2
- data/lib/generators/graphiti/templates/resource_reads_spec.rb.erb +4 -4
- data/lib/generators/graphiti/templates/show_request_spec.rb.erb +2 -2
- data/lib/graphiti/query.rb +24 -5
- data/lib/graphiti/resource/interface.rb +3 -3
- data/lib/graphiti/runner.rb +8 -3
- data/lib/graphiti/scope.rb +13 -0
- data/lib/graphiti/spec_helpers.rb +5 -0
- data/lib/graphiti/version.rb +1 -1
- data/package.json +1 -0
- data/website/sidebars.js +4 -4
- 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: acced292af02bc2826f89f6e1d9388bcc7fdedabada42e4cc65d1bfaf9f713f5
|
|
4
|
+
data.tar.gz: 79f966dc31ccb9b3aee687e7dc31a92e943e17845b6017258e366bebee066446
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22584fd2a83e017219fb8202c965d3d295ac341fed01b2e543355c32722cae741866f3188970ee480018d6063c78b06281045f22934c42b9645de72c6cc9562f
|
|
7
|
+
data.tar.gz: 502371f38ad71f5e901b57ba187be70bb4d7c85c94544324e825207bc03f120fa652d0859fe56744efbdbcf826376dad84a4917444c62a7e30193482bca47700
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
graphiti changelog
|
|
2
2
|
|
|
3
|
+
# [2.0.0-beta.7](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.6...v2.0.0-beta.7) (2026-08-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* dedupe under concurrency and across distinct resources ([800b1a2](https://github.com/graphiti-api/graphiti/commit/800b1a2bf9bb59702efd00afe8e4f54ae06b500e))
|
|
9
|
+
* deduplicate sideloaded entities across include paths ([0c2829a](https://github.com/graphiti-api/graphiti/commit/0c2829a634e9b96e2403ff168be9a48c6a663c78))
|
|
10
|
+
* deprecate SpecHelpers::Sugar in favor of the full helper names ([b155849](https://github.com/graphiti-api/graphiti/commit/b155849f55fe84b2d0911fa4681d82682dfa39ae))
|
|
11
|
+
|
|
3
12
|
# [2.0.0-beta.6](https://github.com/graphiti-api/graphiti/compare/v2.0.0-beta.5...v2.0.0-beta.6) (2026-08-09)
|
|
4
13
|
|
|
5
14
|
|
data/docs/topics/testing.md
CHANGED
|
@@ -134,7 +134,6 @@ require 'graphiti/spec_helpers/rspec'
|
|
|
134
134
|
RSpec.configure do |config|
|
|
135
135
|
config.include FactoryBot::Syntax::Methods
|
|
136
136
|
config.include Graphiti::SpecHelpers::RSpec
|
|
137
|
-
config.include Graphiti::SpecHelpers::Sugar
|
|
138
137
|
config.include Graphiti::Rails::TestHelpers, type: :request
|
|
139
138
|
|
|
140
139
|
# Clean your DB between test runs
|
|
@@ -163,8 +162,6 @@ These helpers ship with Graphiti, under `Graphiti::SpecHelpers`.
|
|
|
163
162
|
|
|
164
163
|
### #jsonapi_data {#jsonapi-data}
|
|
165
164
|
|
|
166
|
-
> Note: for brevity, this method is aliased to `d`
|
|
167
|
-
|
|
168
165
|
The `jsonapi_data` method will parse response data and return a normalized object (`Graphiti::SpecHelpers::Node`). Assert against this the same way you assert against JSON:
|
|
169
166
|
|
|
170
167
|
```ruby
|
|
@@ -183,7 +180,7 @@ expect(data.first_name).to eq('Jane')
|
|
|
183
180
|
To grab a relationship:
|
|
184
181
|
|
|
185
182
|
```ruby
|
|
186
|
-
sideload =
|
|
183
|
+
sideload = jsonapi_data[0].sideload(:comments)
|
|
187
184
|
expect(sideload.id).to eq(123)
|
|
188
185
|
expect(sideload.jsonapi_type).to eq('comments')
|
|
189
186
|
expect(sideload.body).to eq('body')
|
|
@@ -196,7 +193,7 @@ The `sideload` method accepts the *name of the relationship*. It returns a norma
|
|
|
196
193
|
To grab a Link:
|
|
197
194
|
|
|
198
195
|
```ruby
|
|
199
|
-
|
|
196
|
+
jsonapi_data[0].link(:comments, :related)
|
|
200
197
|
```
|
|
201
198
|
|
|
202
199
|
This accepts the relationship name and the link type. It will return the link URL.
|
|
@@ -205,28 +202,26 @@ This accepts the relationship name and the link type. It will return the link UR
|
|
|
205
202
|
|
|
206
203
|
To see the raw JSON response, use `json`.
|
|
207
204
|
|
|
208
|
-
### #
|
|
205
|
+
### #json_date and #json_datetime {#date-and-datetime}
|
|
209
206
|
|
|
210
207
|
In Graphiti, datetimes are rendered in [ISO 8601 format](https://www.iso.org/iso-8601-date-and-time-format.html). This means that straight date comparisons will fail:
|
|
211
208
|
|
|
212
209
|
```ruby
|
|
213
210
|
# WRONG
|
|
214
|
-
expect(
|
|
211
|
+
expect(jsonapi_data[0].created_at).to eq(post.created_at)
|
|
215
212
|
```
|
|
216
213
|
|
|
217
|
-
Instead, use the `
|
|
214
|
+
Instead, use the `json_datetime` helper to convert to ISO 8601 and compare apples to apples:
|
|
218
215
|
|
|
219
216
|
```ruby
|
|
220
217
|
# RIGHT
|
|
221
|
-
expect(
|
|
218
|
+
expect(jsonapi_data[0].created_at).to eq(json_datetime(post.created_at))
|
|
222
219
|
```
|
|
223
220
|
|
|
224
|
-
Similarly, there's a `
|
|
221
|
+
Similarly, there's a `json_date` helper as well.
|
|
225
222
|
|
|
226
223
|
### #jsonapi_errors {#jsonapi-errors}
|
|
227
224
|
|
|
228
|
-
> This method is aliased to `errors` for brevity
|
|
229
|
-
|
|
230
225
|
To parse an [Errors Payload](http://jsonapi.org/format/#errors):
|
|
231
226
|
|
|
232
227
|
```ruby
|
|
@@ -261,7 +256,7 @@ Resource tests have two helpers, both different ways to execute a query.
|
|
|
261
256
|
```ruby
|
|
262
257
|
it 'works' do
|
|
263
258
|
render
|
|
264
|
-
expect(
|
|
259
|
+
expect(jsonapi_data[0].first_name).to eq('Jane')
|
|
265
260
|
json # => { data: { type: 'employees', ... } }
|
|
266
261
|
end
|
|
267
262
|
```
|
|
@@ -275,6 +270,33 @@ it 'works' do
|
|
|
275
270
|
end
|
|
276
271
|
```
|
|
277
272
|
|
|
273
|
+
### Resource Matchers {#resource-matchers}
|
|
274
|
+
|
|
275
|
+
For one-line assertions about a Resource's shape, use the built-in matchers. They're included automatically in `type: :resource` specs and expect a Resource instance as the subject:
|
|
276
|
+
|
|
277
|
+
```ruby
|
|
278
|
+
RSpec.describe PostResource, type: :resource do
|
|
279
|
+
subject { described_class.new }
|
|
280
|
+
|
|
281
|
+
it { is_expected.to belong_to_resource(:author) }
|
|
282
|
+
it { is_expected.to have_many_resources(:comments) }
|
|
283
|
+
it { is_expected.to have_one_resource(:detail) }
|
|
284
|
+
it { is_expected.to expose_attribute(:title, :string) }
|
|
285
|
+
it { is_expected.to filter_attribute(:title, :string) }
|
|
286
|
+
end
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Each matcher accepts `with_options` to assert configuration:
|
|
290
|
+
|
|
291
|
+
```ruby
|
|
292
|
+
it do
|
|
293
|
+
is_expected.to belong_to_resource(:author)
|
|
294
|
+
.with_options(foreign_key: :author_id, resource: AuthorResource)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it { is_expected.to expose_attribute(:title, :string).with_options(writable: false) }
|
|
298
|
+
```
|
|
299
|
+
|
|
278
300
|
### API Test Helpers {#api-test-helpers}
|
|
279
301
|
|
|
280
302
|
When executing an API test request, always use the `jsonapi_` doppelgänger:
|
|
@@ -378,7 +400,7 @@ describe 'filtering' do
|
|
|
378
400
|
|
|
379
401
|
it 'works' do
|
|
380
402
|
render
|
|
381
|
-
expect(
|
|
403
|
+
expect(jsonapi_data.map(&:id)).to eq([employee2.id])
|
|
382
404
|
end
|
|
383
405
|
end
|
|
384
406
|
end
|
|
@@ -401,7 +423,7 @@ describe 'sorting' do
|
|
|
401
423
|
|
|
402
424
|
it 'works' do
|
|
403
425
|
render
|
|
404
|
-
expect(
|
|
426
|
+
expect(jsonapi_data.map(&:id)).to eq([
|
|
405
427
|
employee1.id,
|
|
406
428
|
employee2.id
|
|
407
429
|
])
|
|
@@ -415,7 +437,7 @@ describe 'sorting' do
|
|
|
415
437
|
|
|
416
438
|
it 'works' do
|
|
417
439
|
render
|
|
418
|
-
expect(
|
|
440
|
+
expect(jsonapi_data.map(&:id)).to eq([
|
|
419
441
|
employee2.id,
|
|
420
442
|
employee1.id
|
|
421
443
|
])
|
|
@@ -447,7 +469,7 @@ describe 'sideloading' do
|
|
|
447
469
|
|
|
448
470
|
it 'returns position with historical index == 1' do
|
|
449
471
|
render
|
|
450
|
-
sl =
|
|
472
|
+
sl = jsonapi_data[0].sideload(:current_position)
|
|
451
473
|
expect(sl.jsonapi_type).to eq('positions')
|
|
452
474
|
expect(sl.id).to eq(pos2.id)
|
|
453
475
|
end
|
|
@@ -669,9 +691,9 @@ RSpec.describe "employees#index", type: :request do
|
|
|
669
691
|
expect(EmployeeResource).to receive(:all).and_call_original
|
|
670
692
|
make_request
|
|
671
693
|
expect(response.status).to eq(200)
|
|
672
|
-
expect(
|
|
694
|
+
expect(jsonapi_data.map(&:jsonapi_type).uniq)
|
|
673
695
|
.to match_array(['employees'])
|
|
674
|
-
expect(
|
|
696
|
+
expect(jsonapi_data.map(&:id))
|
|
675
697
|
.to match_array([employee1.id, employee2.id])
|
|
676
698
|
end
|
|
677
699
|
end
|
|
@@ -694,8 +716,8 @@ describe 'basic fetch' do
|
|
|
694
716
|
expect(EmployeeResource).to receive(:find).and_call_original
|
|
695
717
|
make_request
|
|
696
718
|
expect(response.status).to eq(200)
|
|
697
|
-
expect(
|
|
698
|
-
expect(
|
|
719
|
+
expect(jsonapi_data.jsonapi_type).to eq('employees')
|
|
720
|
+
expect(jsonapi_data.id).to eq(employee.id)
|
|
699
721
|
end
|
|
700
722
|
end
|
|
701
723
|
```
|
|
@@ -843,7 +865,7 @@ it 'works' do
|
|
|
843
865
|
Graphiti.with_context ctx do
|
|
844
866
|
render
|
|
845
867
|
end
|
|
846
|
-
expect(
|
|
868
|
+
expect(jsonapi_data[0].salary).to eq(100_000)
|
|
847
869
|
end
|
|
848
870
|
```
|
|
849
871
|
|
data/docs/upgrading.md
CHANGED
|
@@ -214,6 +214,7 @@ Every name below still works, warns, and will be removed in the next major. They
|
|
|
214
214
|
| --- | --- |
|
|
215
215
|
| `require "graphiti_spec_helpers/rspec"` | `require "graphiti/spec_helpers/rspec"` |
|
|
216
216
|
| `GraphitiSpecHelpers::RSpec` / `::Sugar` / `::Errors::*` | `Graphiti::SpecHelpers::*` |
|
|
217
|
+
| `include Graphiti::SpecHelpers::Sugar` (`d`, `included`, `errors`, `dt`) | call `jsonapi_data`, `jsonapi_included`, `jsonapi_errors`, `json_datetime` directly |
|
|
217
218
|
| `require "graphiti-rails"` | remove / no longer needed |
|
|
218
219
|
| `include Graphiti::Rails` | `include Graphiti::Rails::Controller`|
|
|
219
220
|
| `include Graphiti::Responders` | `include Graphiti::Rails::Responders` |
|
|
@@ -15,8 +15,8 @@ RSpec.describe "<%= type %>#index", type: :request do
|
|
|
15
15
|
expect(<%= resource_class %>).to receive(:all).and_call_original
|
|
16
16
|
make_request
|
|
17
17
|
expect(response.status).to eq(200), response.body
|
|
18
|
-
expect(
|
|
19
|
-
expect(
|
|
18
|
+
expect(jsonapi_data.map(&:jsonapi_type).uniq).to match_array(['<%= type %>'])
|
|
19
|
+
expect(jsonapi_data.map(&:<%= id_or_rawid %>)).to match_array([<%= var %>1.id, <%= var %>2.id])
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -11,7 +11,7 @@ RSpec.describe <%= resource_class %>, type: :resource do
|
|
|
11
11
|
expect(data.jsonapi_type).to eq('<%= type %>')
|
|
12
12
|
<%- attributes.each do |a| -%>
|
|
13
13
|
<%- if [:created_at, :updated_at].include?(a.name.to_sym) -%>
|
|
14
|
-
expect(data.<%= a.name %>).to eq(
|
|
14
|
+
expect(data.<%= a.name %>).to eq(json_datetime(<%= file_name %>.<%= a.name %>))
|
|
15
15
|
<%- else -%>
|
|
16
16
|
expect(data.<%= a.name %>).to eq(<%= file_name %>.<%= a.name %>)
|
|
17
17
|
<%- end -%>
|
|
@@ -31,7 +31,7 @@ RSpec.describe <%= resource_class %>, type: :resource do
|
|
|
31
31
|
|
|
32
32
|
it 'works' do
|
|
33
33
|
render
|
|
34
|
-
expect(
|
|
34
|
+
expect(jsonapi_data.map(&:<%= id_or_rawid %>)).to eq([<%= var %>2.id])
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
end
|
|
@@ -48,7 +48,7 @@ RSpec.describe <%= resource_class %>, type: :resource do
|
|
|
48
48
|
|
|
49
49
|
it 'works' do
|
|
50
50
|
render
|
|
51
|
-
expect(
|
|
51
|
+
expect(jsonapi_data.map(&:<%= id_or_rawid %>)).to eq([
|
|
52
52
|
<%= var %>1.id,
|
|
53
53
|
<%= var %>2.id
|
|
54
54
|
]<%= sort_raw_ids %>)
|
|
@@ -62,7 +62,7 @@ RSpec.describe <%= resource_class %>, type: :resource do
|
|
|
62
62
|
|
|
63
63
|
it 'works' do
|
|
64
64
|
render
|
|
65
|
-
expect(
|
|
65
|
+
expect(jsonapi_data.map(&:<%= id_or_rawid %>)).to eq([
|
|
66
66
|
<%= var %>2.id,
|
|
67
67
|
<%= var %>1.id
|
|
68
68
|
]<%= sort_raw_ids_descending %>)
|
|
@@ -14,8 +14,8 @@ RSpec.describe "<%= type %>#show", type: :request do
|
|
|
14
14
|
expect(<%= resource_class %>).to receive(:find).and_call_original
|
|
15
15
|
make_request
|
|
16
16
|
expect(response.status).to eq(200)
|
|
17
|
-
expect(
|
|
18
|
-
expect(
|
|
17
|
+
expect(jsonapi_data.jsonapi_type).to eq('<%= type %>')
|
|
18
|
+
expect(jsonapi_data.<%= id_or_rawid %>).to eq(<%= var %>.id)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
data/lib/graphiti/query.rb
CHANGED
|
@@ -4,8 +4,15 @@ module Graphiti
|
|
|
4
4
|
class Query
|
|
5
5
|
attr_reader :resource, :association_name, :params, :action
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
def initialize(resource, params, *positional, association_name: nil, nested_include: nil, parents: [], action: nil)
|
|
8
|
+
if positional.any?
|
|
9
|
+
Graphiti::DEPRECATOR.warn("Passing Query.new trailing arguments positionally is deprecated. Use association_name:/nested_include:/parents:/action: keywords.")
|
|
10
|
+
association_name ||= positional[0]
|
|
11
|
+
nested_include ||= positional[1]
|
|
12
|
+
parents = positional[2] if positional.length > 2
|
|
13
|
+
action ||= positional[3]
|
|
14
|
+
end
|
|
15
|
+
|
|
9
16
|
@resource = resource
|
|
10
17
|
@association_name = association_name
|
|
11
18
|
@params = params
|
|
@@ -21,6 +28,13 @@ module Graphiti
|
|
|
21
28
|
!!@association_name
|
|
22
29
|
end
|
|
23
30
|
|
|
31
|
+
# Concurrent::Map because sideload scopes resolve on pool threads
|
|
32
|
+
def entity_map
|
|
33
|
+
return root.entity_map unless root == self
|
|
34
|
+
|
|
35
|
+
@entity_map ||= Concurrent::Map.new
|
|
36
|
+
end
|
|
37
|
+
|
|
24
38
|
def top_level?
|
|
25
39
|
!association?
|
|
26
40
|
end
|
|
@@ -110,9 +124,10 @@ module Graphiti
|
|
|
110
124
|
relationship_name = sideload ? sideload.name : key
|
|
111
125
|
hash[relationship_name] = Query.new sl_resource,
|
|
112
126
|
@params,
|
|
113
|
-
key,
|
|
114
|
-
sub_hash,
|
|
115
|
-
query_parents,
|
|
127
|
+
association_name: key,
|
|
128
|
+
nested_include: sub_hash,
|
|
129
|
+
parents: query_parents,
|
|
130
|
+
action: :all
|
|
116
131
|
else
|
|
117
132
|
handle_missing_sideload(key)
|
|
118
133
|
end
|
|
@@ -124,6 +139,10 @@ module Graphiti
|
|
|
124
139
|
@parents ||= []
|
|
125
140
|
end
|
|
126
141
|
|
|
142
|
+
def root
|
|
143
|
+
parents.first || self
|
|
144
|
+
end
|
|
145
|
+
|
|
127
146
|
def fields
|
|
128
147
|
@fields ||= begin
|
|
129
148
|
hash = parse_fieldset(@params[:fields] || {})
|
|
@@ -17,7 +17,7 @@ module Graphiti
|
|
|
17
17
|
|
|
18
18
|
# @api private
|
|
19
19
|
def _all(params, opts, base_scope)
|
|
20
|
-
runner = Runner.new(self, params, opts.delete(:query), :all)
|
|
20
|
+
runner = Runner.new(self, params, query: opts.delete(:query), action: :all)
|
|
21
21
|
opts[:params] = params
|
|
22
22
|
runner.proxy(base_scope, opts.merge(caching_options))
|
|
23
23
|
end
|
|
@@ -36,7 +36,7 @@ module Graphiti
|
|
|
36
36
|
params[:filter] ||= {}
|
|
37
37
|
params[:filter][:id] = id if id
|
|
38
38
|
|
|
39
|
-
runner = Runner.new(self, params,
|
|
39
|
+
runner = Runner.new(self, params, action: :find)
|
|
40
40
|
|
|
41
41
|
find_options = {
|
|
42
42
|
single: true,
|
|
@@ -56,7 +56,7 @@ module Graphiti
|
|
|
56
56
|
# Wrap models fetched outside graphiti so they render like any other proxy
|
|
57
57
|
def wrap(models, base_scope = nil)
|
|
58
58
|
validate_wrap_models!(models)
|
|
59
|
-
runner = Runner.new(self, {},
|
|
59
|
+
runner = Runner.new(self, {}, action: :find)
|
|
60
60
|
runner.proxy(base_scope, bypass_required_filters: true).tap do |proxy|
|
|
61
61
|
proxy.data = models
|
|
62
62
|
end
|
data/lib/graphiti/runner.rb
CHANGED
|
@@ -3,8 +3,13 @@ module Graphiti
|
|
|
3
3
|
attr_reader :params
|
|
4
4
|
attr_reader :deserialized_payload
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
def initialize(resource_class, params, *positional, query: nil, action: nil)
|
|
7
|
+
if positional.any?
|
|
8
|
+
Graphiti::DEPRECATOR.warn("Passing query/action to Runner.new positionally is deprecated. Use query:/action: keywords.")
|
|
9
|
+
query ||= positional[0]
|
|
10
|
+
action ||= positional[1]
|
|
11
|
+
end
|
|
12
|
+
|
|
8
13
|
@resource_class = resource_class
|
|
9
14
|
@params = params
|
|
10
15
|
@query = query
|
|
@@ -30,7 +35,7 @@ module Graphiti
|
|
|
30
35
|
end
|
|
31
36
|
|
|
32
37
|
def query
|
|
33
|
-
@query ||= Query.new(jsonapi_resource, params,
|
|
38
|
+
@query ||= Query.new(jsonapi_resource, params, action: @action)
|
|
34
39
|
end
|
|
35
40
|
|
|
36
41
|
def query_hash
|
data/lib/graphiti/scope.rb
CHANGED
|
@@ -154,12 +154,25 @@ module Graphiti
|
|
|
154
154
|
payload[:results]
|
|
155
155
|
}
|
|
156
156
|
resolved.compact!
|
|
157
|
+
deduplicate_entities!(resolved)
|
|
157
158
|
assign_serializer(resolved)
|
|
158
159
|
yield resolved if block_given?
|
|
159
160
|
@opts[:after_resolve]&.call(resolved)
|
|
160
161
|
resolved
|
|
161
162
|
end
|
|
162
163
|
|
|
164
|
+
# Must run before sideloads assign, so every include path populates the
|
|
165
|
+
# canonical instance. The resource class in the key keeps two resources
|
|
166
|
+
# serving the same model from sharing an instance and a serializer.
|
|
167
|
+
def deduplicate_entities!(resolved)
|
|
168
|
+
resolved.map! do |record|
|
|
169
|
+
next record unless record.respond_to?(:id) && !record.id.nil?
|
|
170
|
+
|
|
171
|
+
key = [@resource.class, record.class, record.id]
|
|
172
|
+
@query.entity_map.compute_if_absent(key) { record }
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
163
176
|
def each_applicable_sideload
|
|
164
177
|
@query.sideloads.each_pair do |name, sideload_query|
|
|
165
178
|
sideload = @resource.class.sideload(name)
|
|
@@ -26,6 +26,11 @@ module Graphiti
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
module Sugar
|
|
29
|
+
def self.included(base)
|
|
30
|
+
Graphiti::DEPRECATOR.warn("Graphiti::SpecHelpers::Sugar is deprecated. Call jsonapi_data, jsonapi_included, jsonapi_errors, json_date and json_datetime directly.")
|
|
31
|
+
super
|
|
32
|
+
end
|
|
33
|
+
|
|
29
34
|
def d
|
|
30
35
|
jsonapi_data
|
|
31
36
|
end
|
data/lib/graphiti/version.rb
CHANGED
data/package.json
CHANGED
data/website/sidebars.js
CHANGED
|
@@ -21,18 +21,18 @@ module.exports = {
|
|
|
21
21
|
type: 'category',
|
|
22
22
|
label: 'Topics',
|
|
23
23
|
items: [
|
|
24
|
-
'topics/authorization',
|
|
25
|
-
'topics/error-handling',
|
|
26
24
|
'topics/testing',
|
|
25
|
+
'topics/error-handling',
|
|
26
|
+
'topics/authorization',
|
|
27
27
|
'topics/debugging',
|
|
28
28
|
'topics/caching',
|
|
29
29
|
'topics/etags',
|
|
30
30
|
'topics/json-attributes',
|
|
31
|
-
'topics/
|
|
31
|
+
'topics/customizing-sideloads',
|
|
32
32
|
'concepts/backends-and-models',
|
|
33
33
|
'topics/without-activerecord',
|
|
34
34
|
'topics/openstruct-models',
|
|
35
|
-
'topics/
|
|
35
|
+
'topics/remote-resources',
|
|
36
36
|
'topics/hopping-relationships',
|
|
37
37
|
],
|
|
38
38
|
},
|