graphiti-activegraph 0.2.0 → 1.0.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/.github/workflows/specs.yml +17 -3
- data/.gitignore +3 -0
- data/CHANGELOG.md +17 -70
- data/CHANGELOG_PRE_1.0.0.md +70 -0
- data/README.md +68 -0
- data/graphiti-activegraph.gemspec +2 -0
- data/lib/graphiti/active_graph/adapters/active_graph.rb +1 -1
- data/lib/graphiti/active_graph/extensions/context.rb +17 -0
- data/lib/graphiti/active_graph/extensions/resources/authorizationable.rb +29 -0
- data/lib/graphiti/active_graph/extensions/resources/payload_combinable.rb +24 -0
- data/lib/graphiti/active_graph/extensions/resources/preloadable.rb +19 -0
- data/lib/graphiti/active_graph/extensions/resources/rel.rb +19 -0
- data/lib/graphiti/active_graph/resource.rb +45 -20
- data/lib/graphiti/active_graph/{resource → resources}/interface.rb +1 -1
- data/lib/graphiti/active_graph/{resource → resources}/persistence.rb +1 -1
- data/lib/graphiti/active_graph/scope.rb +27 -0
- data/lib/graphiti/active_graph/scoping/association_eager_load.rb +35 -0
- data/lib/graphiti/active_graph/version.rb +1 -1
- data/lib/graphiti/sidepost_configuration.rb +1 -0
- data/lib/graphiti-activegraph.rb +6 -4
- metadata +42 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0928b60dbd846d64a29c21e84023b471b619e437261e1d8b77f840e5c633dd81'
|
4
|
+
data.tar.gz: 69afd454fcf50c4ffa50930de69bea8d182c5e32681c9be2c9c33b676719f102
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b6675d6ee443f716836b6ce3680597d2ee9abcb5ff5999ba8cd452d03128d3794a5f0bc663d311d99401f4549887f77347be86d0fc84430c5b5b3e869b0bcf10
|
7
|
+
data.tar.gz: 1f972ef62c9bf15ba0b0881206cb09bcb5986a8cd2f28875d703e3d372d61ce89e19cf12f049b6609416ead6d52704185f5791554e5967631d90327ef610e52a
|
data/.github/workflows/specs.yml
CHANGED
@@ -18,20 +18,34 @@ jobs:
|
|
18
18
|
strategy:
|
19
19
|
fail-fast: false
|
20
20
|
matrix:
|
21
|
-
ruby-version: [
|
21
|
+
ruby-version: [ ruby-3.4.2, ruby-3.3.7, ruby-3.2.7 ] # Removed 'jruby' till https://github.com/jruby/jruby/issues/8642 is fixed
|
22
|
+
neo4j: [ 5.23.0 ]
|
23
|
+
include:
|
24
|
+
- ruby: jruby
|
25
|
+
java-version: 17
|
22
26
|
env:
|
23
27
|
JRUBY_OPTS: --debug -J-Xmx1280m -Xcompile.invokedynamic=false -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -J-noverify -Xcompile.mode=OFF
|
24
28
|
steps:
|
29
|
+
- name: Start neo4j
|
30
|
+
run: docker run --name neo4j --env NEO4J_AUTH=neo4j/password --env NEO4J_ACCEPT_LICENSE_AGREEMENT=yes --env NEO4J_dbms_directories_import= -p7687:7687 -p7474:7474 -v `pwd`/tmp:/var/lib/neo4j/import --rm neo4j:${{ matrix.neo4j }}-enterprise &
|
31
|
+
|
25
32
|
- uses: actions/checkout@v3
|
33
|
+
|
26
34
|
- name: Set up Ruby
|
27
35
|
uses: ruby/setup-ruby@v1
|
28
36
|
with:
|
29
37
|
ruby-version: ${{ matrix.ruby-version }}
|
30
38
|
bundler-cache: true
|
39
|
+
|
31
40
|
- name: Set up Java
|
32
|
-
uses: actions/setup-java@
|
41
|
+
uses: actions/setup-java@v4
|
42
|
+
if: matrix.java-version
|
33
43
|
with:
|
34
44
|
distribution: 'temurin'
|
35
|
-
java-version:
|
45
|
+
java-version: ${{ matrix.java-version }}
|
46
|
+
|
47
|
+
- name: Wait for neo4j
|
48
|
+
run: while [ $((curl localhost:7474/ > /dev/null 2>&1); echo $?) -ne 0 ]; do sleep 1; done
|
49
|
+
|
36
50
|
- name: Run tests
|
37
51
|
run: bundle exec rspec
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,80 +1,27 @@
|
|
1
|
-
|
1
|
+
# Changelog
|
2
2
|
|
3
|
-
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
-
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
7
|
|
7
|
-
|
8
|
+
## [Unreleased]
|
8
9
|
|
9
|
-
|
10
|
+
## [1.0.0] - 2025-03-18
|
10
11
|
|
11
|
-
|
12
|
+
### Added
|
12
13
|
|
13
|
-
|
14
|
+
- **MRI Support**: Introduced compatibility with MRI (Matz's Ruby Interpreter), expanding the gem's usability beyond JRuby (#38).
|
15
|
+
- **Documentation Updates**: Expanded the README to provide clearer guidance on gem usage and integration (#38).
|
16
|
+
- **Sideloading Workflow**: Enhanced scoping mechanisms and added support for eager loading associations to improve data retrieval efficiency and flexibility (#38).
|
14
17
|
|
15
|
-
|
18
|
+
### Changed
|
19
|
+
- **Resource Class**: Instead of modifying the `Graphiti::Resource` class, we now define `Graphiti::ActiveGraph::Resource`,
|
20
|
+
which must be inherited in all resource classes to enable ActiveGraph support (#38).
|
16
21
|
|
17
|
-
|
22
|
+
---
|
18
23
|
|
19
|
-
|
24
|
+
*Note: For details on changes prior to version 1.0.0, please refer to the [`CHANGELOG_PRE_1.0.0.md`](CHANGELOG_PRE_1.0.0.md) file.*
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
## 0.1.15 (21-06-2022)
|
24
|
-
|
25
|
-
Features:
|
26
|
-
|
27
|
-
- Relationships mentioned in sparse field param (and not in include), will now be returned in relationship block of response
|
28
|
-
|
29
|
-
## 0.1.20
|
30
|
-
|
31
|
-
Features:
|
32
|
-
|
33
|
-
- With graphiti config variable "allow_sidepost" you can allow/disallow sideposting, by default it is allowed.
|
34
|
-
|
35
|
-
## 0.1.21
|
36
|
-
|
37
|
-
Fixes:
|
38
|
-
|
39
|
-
- Runner#proxy keyword arguments
|
40
|
-
|
41
|
-
## 0.1.22
|
42
|
-
|
43
|
-
Fixes:
|
44
|
-
|
45
|
-
- when rendering preloaded resources, we were not applying scoping. Now we are skipping around_scoping callback too.
|
46
|
-
|
47
|
-
## 0.1.23 (29-04-2024)
|
48
|
-
|
49
|
-
Features:
|
50
|
-
|
51
|
-
- Added support for UUID
|
52
|
-
|
53
|
-
## 0.1.24 (18-06-2024)
|
54
|
-
|
55
|
-
Features:
|
56
|
-
|
57
|
-
- Added preliminary support for Sideload backed by function instead of model association
|
58
|
-
|
59
|
-
## 0.1.25 (04-12-2024)
|
60
|
-
|
61
|
-
Features:
|
62
|
-
|
63
|
-
- Added support to preload extra_fields for the main resource, replacing N+1 queries with a single query. This does not apply to sideloaded resources.
|
64
|
-
|
65
|
-
## 0.2.0 (01-24-2025)
|
66
|
-
|
67
|
-
Features:
|
68
|
-
|
69
|
-
- Added MRI support
|
70
|
-
- Added support for rails 8
|
71
|
-
|
72
|
-
Breaking changes:
|
73
|
-
|
74
|
-
- Removed support for graphiti <= 1.6.3
|
75
|
-
|
76
|
-
<!-- ### [version (DD-MM-YYYY)] -->
|
77
|
-
<!-- Breaking changes:-->
|
78
|
-
<!-- Features:-->
|
79
|
-
<!-- Fixes:-->
|
80
|
-
<!-- Misc:-->
|
26
|
+
[unreleased]: https://github.com/mrhardikjoshi/graphiti-activegraph/compare/v1.0.0...master
|
27
|
+
[1.0.0]: https://github.com/mrhardikjoshi/graphiti-activegraph/compare/9f837108ae57287c65b0f6fd2609dd56a95cd461...v1.0.0
|
@@ -0,0 +1,70 @@
|
|
1
|
+
## 0.1.8 (09-06-2021)
|
2
|
+
|
3
|
+
Features:
|
4
|
+
|
5
|
+
- Added support for polymorphic relationship.
|
6
|
+
|
7
|
+
## 0.1.13 (21-12-2021)
|
8
|
+
|
9
|
+
Features:
|
10
|
+
|
11
|
+
- Supports Jruby-9.3.2.0
|
12
|
+
|
13
|
+
## 0.1.14 (21-12-2021)
|
14
|
+
|
15
|
+
Features:
|
16
|
+
|
17
|
+
- Adding unpaginated query to resource proxy with preloaded records. This will help in getting count on API.
|
18
|
+
|
19
|
+
## 0.1.15 (21-06-2022)
|
20
|
+
|
21
|
+
Features:
|
22
|
+
|
23
|
+
- Relationships mentioned in sparse field param (and not in include), will now be returned in relationship block of response
|
24
|
+
|
25
|
+
## 0.1.20
|
26
|
+
|
27
|
+
Features:
|
28
|
+
|
29
|
+
- With graphiti config variable "allow_sidepost" you can allow/disallow sideposting, by default it is allowed.
|
30
|
+
|
31
|
+
## 0.1.21
|
32
|
+
|
33
|
+
Fixes:
|
34
|
+
|
35
|
+
- Runner#proxy keyword arguments
|
36
|
+
|
37
|
+
## 0.1.22
|
38
|
+
|
39
|
+
Fixes:
|
40
|
+
|
41
|
+
- when rendering preloaded resources, we were not applying scoping. Now we are skipping around_scoping callback too.
|
42
|
+
|
43
|
+
## 0.1.23 (29-04-2024)
|
44
|
+
|
45
|
+
Features:
|
46
|
+
|
47
|
+
- Added support for UUID
|
48
|
+
|
49
|
+
## 0.1.24 (18-06-2024)
|
50
|
+
|
51
|
+
Features:
|
52
|
+
|
53
|
+
- Added preliminary support for Sideload backed by function instead of model association
|
54
|
+
|
55
|
+
## 0.1.25 (04-12-2024)
|
56
|
+
|
57
|
+
Features:
|
58
|
+
|
59
|
+
- Added support to preload extra_fields for the main resource, replacing N+1 queries with a single query. This does not apply to sideloaded resources.
|
60
|
+
|
61
|
+
## 0.2.0 (01-24-2025)
|
62
|
+
|
63
|
+
Features:
|
64
|
+
|
65
|
+
- Added MRI support
|
66
|
+
- Added support for rails 8
|
67
|
+
|
68
|
+
Breaking changes:
|
69
|
+
|
70
|
+
- Removed support for graphiti <= 1.6.3
|
data/README.md
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# Graphiti ActiveGraph
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/graphiti-activegraph) [](https://github.com/mrhardikjoshi/graphiti-activegraph/actions?query=branch%3Amaster) [](LICENSE.txt)
|
4
|
+
|
5
|
+
An adapter to make Graphiti work with the ActiveGraph(former Neo4jrb) OGM. This gem allows you to easily build [jsonapi.org](https://jsonapi.org) compatible APIs for GraphDB using [Graphiti](https://www.graphiti.dev) and [ActiveGraph](https://github.com/neo4jrb/activegraph).
|
6
|
+
|
7
|
+
### Installation
|
8
|
+
Add this line to your application's `Gemfile`:
|
9
|
+
```ruby
|
10
|
+
gem 'graphiti-activegraph'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
```shell
|
15
|
+
bundle install
|
16
|
+
```
|
17
|
+
|
18
|
+
Or install it yourself as:
|
19
|
+
```shell
|
20
|
+
gem install graphiti-activegraph
|
21
|
+
```
|
22
|
+
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
While defining a Resource class, inherit it from `Graphiti::ActiveGraph::Resource`
|
26
|
+
```ruby
|
27
|
+
class PlanetResource < Graphiti::ActiveGraph::Resource
|
28
|
+
```
|
29
|
+
|
30
|
+
For model backed by `ApplicationRelationship` instead of `ApplicationNode`, we have to set `relationship_resource` to `true` while defining resource class.
|
31
|
+
```ruby
|
32
|
+
class RelationshipBackedResource < Graphiti::ActiveGraph::Resource
|
33
|
+
self.relationship_resource = true
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
### Documentation
|
38
|
+
##### **Key Differences from Graphiti**
|
39
|
+
- **Efficient Sideloading:**
|
40
|
+
Unlike Graphiti, which executes multiple queries for sideloading, graphiti-activegraph leverages `with_ordered_associations` from ActiveGraph to fetch sideloaded data in a single query, improving performance.
|
41
|
+
|
42
|
+
- **Sideposting Behavior:**
|
43
|
+
graphiti-activegraph allows assigning and unassigning relationships via sideposting but does not support modifying a resource’s attributes through sideposting.
|
44
|
+
|
45
|
+
- **Thread Context Handling:**
|
46
|
+
Graphiti stores context using `Thread.current[]`, which does not persist across different fibers within the same thread. In graphiti-activegraph, when running on MRI (non-JRuby environments), the gem uses `thread_variable_get` and `thread_variable_set`. Ensuring the context remains consistent across different fibers in the same thread.
|
47
|
+
|
48
|
+
##### **New Features in graphiti-activegraph**
|
49
|
+
###### Rendering Preloaded Objects Without Extra Queries
|
50
|
+
graphiti-activegraph introduces two new methods on the Graphiti resource class:
|
51
|
+
`with_preloaded_obj(record, params)` – Renders a single preloaded ActiveGraph object without querying the database.
|
52
|
+
`all_with_preloaded(records, params)` – Renders multiple preloaded ActiveGraph objects without additional queries.
|
53
|
+
**Note:** These methods assume that the provided records are final and will not apply Graphiti’s filtering, sorting, or scoping logic.
|
54
|
+
|
55
|
+
### Contributing
|
56
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/mrhardikjoshi/graphiti-activegraph. This project is intended to be a safe, welcoming space for collaboration.
|
57
|
+
|
58
|
+
### Release
|
59
|
+
1. Make sure version file is updated/incremented in master branch
|
60
|
+
2. git checkout master
|
61
|
+
3. git pull origin master
|
62
|
+
4. git tag v1.2.3
|
63
|
+
5. git push origin v1.2.3
|
64
|
+
6. gem build graphiti-activegraph.gemspec
|
65
|
+
7. gem push graphiti-activegraph-1.2.3.gem
|
66
|
+
|
67
|
+
### License
|
68
|
+
The gem is available as open-source under the terms of the MIT License.
|
@@ -23,6 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency 'graphiti_spec_helpers', '>= 1.0.0'
|
24
24
|
spec.add_development_dependency 'standard'
|
25
25
|
spec.add_development_dependency 'pry'
|
26
|
+
spec.add_development_dependency 'ffaker'
|
27
|
+
spec.add_development_dependency 'factory_bot_rails'
|
26
28
|
spec.add_development_dependency 'rake', '>= 10.0'
|
27
29
|
spec.add_development_dependency 'rspec', '>= 3.9.0'
|
28
30
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Graphiti::ActiveGraph::Extensions
|
2
|
+
require 'ostruct' if RUBY_PLATFORM != 'java'
|
3
|
+
|
4
|
+
module Context
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
class_methods do
|
8
|
+
def context
|
9
|
+
Thread.current.thread_variable_get(:context) || {}.tap(&method(:context=))
|
10
|
+
end
|
11
|
+
|
12
|
+
def context=(val)
|
13
|
+
Thread.current.thread_variable_set(:context, val)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Graphiti::ActiveGraph::Extensions::Resources
|
2
|
+
module Authorizationable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class << self
|
7
|
+
attr_reader :authorize_attributes
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class_methods do
|
12
|
+
def attribute_authorization
|
13
|
+
@authorize_attributes = true
|
14
|
+
end
|
15
|
+
|
16
|
+
def authorize_attributes?
|
17
|
+
@authorize_attributes
|
18
|
+
end
|
19
|
+
|
20
|
+
def readable_attributes
|
21
|
+
attributes.select { |_attr_name, options_map| options_map[:readable] }
|
22
|
+
end
|
23
|
+
|
24
|
+
def readable_sideloads
|
25
|
+
sideloads.select { |_sideloads_name, sideload_obj| sideload_obj.readable? }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Graphiti::ActiveGraph::Extensions::Resources
|
2
|
+
module PayloadCombinable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
def combine(attributes, relationships)
|
7
|
+
attributes.merge(relationship_attributes(relationships))
|
8
|
+
end
|
9
|
+
|
10
|
+
def relationship_attributes(relationships)
|
11
|
+
relationships.map { |k, v| [k, extract_ids(v)] }.to_h
|
12
|
+
end
|
13
|
+
|
14
|
+
def extract_ids(object)
|
15
|
+
object.is_a?(Array) ? object.map { |o| extract_ids(o) } : object[:attributes][:id]
|
16
|
+
end
|
17
|
+
|
18
|
+
def remove_undeclared_attributes(attr_map)
|
19
|
+
permitted_attrs = all_attributes.keys
|
20
|
+
attr_map.select! { |attr_name, _value| permitted_attrs.include?(attr_name.to_sym) }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Graphiti::ActiveGraph::Extensions::Resources
|
2
|
+
module Preloadable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
def with_preloaded_obj(obj, params)
|
7
|
+
id = params[:data].try(:[], :id) || params.delete(:id)
|
8
|
+
params[:filter] ||= {}
|
9
|
+
params[:filter][:id] = id if id
|
10
|
+
|
11
|
+
build(params, nil, raise_on_missing: false, preloaded: obj)
|
12
|
+
end
|
13
|
+
|
14
|
+
def all_with_preloaded(obj_arr, params)
|
15
|
+
build(params, nil, single: false, raise_on_missing: false, preloaded: obj_arr)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Graphiti::ActiveGraph::Extensions::Resources
|
2
|
+
module Rel
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def relation_resource?
|
6
|
+
self.class.relation_resource?
|
7
|
+
end
|
8
|
+
|
9
|
+
class_methods do
|
10
|
+
def relation_resource?
|
11
|
+
config[:relation_resource] || false
|
12
|
+
end
|
13
|
+
|
14
|
+
def relationship_resource=(value)
|
15
|
+
config[:relation_resource] = value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -1,41 +1,52 @@
|
|
1
1
|
module Graphiti
|
2
2
|
module ActiveGraph
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
class Resource < Graphiti::Resource
|
4
|
+
include Extensions::Resources::Authorizationable
|
5
|
+
include Extensions::Resources::PayloadCombinable
|
6
|
+
include Extensions::Resources::Preloadable
|
7
|
+
include Extensions::Resources::Rel
|
8
|
+
|
9
|
+
self.adapter = Adapters::ActiveGraph
|
10
|
+
self.abstract_class = true
|
11
|
+
|
12
|
+
def self.use_uuid
|
13
|
+
define_singleton_method(:inherited) do |klass|
|
14
|
+
super(klass)
|
15
|
+
klass.attribute :id, :uuid
|
16
|
+
end
|
6
17
|
end
|
7
18
|
|
8
|
-
def
|
9
|
-
config[:relation_resource] = value
|
19
|
+
def self.guard_nil_id!(params)
|
10
20
|
end
|
11
21
|
|
12
|
-
def
|
13
|
-
|
14
|
-
|
15
|
-
params[:filter][:id] = id if id
|
22
|
+
def self.extra_attribute?(name)
|
23
|
+
extra_attributes.has_key?(name)
|
24
|
+
end
|
16
25
|
|
17
|
-
|
26
|
+
def self.sideload_config(sideload_name)
|
27
|
+
config[:sideloads][sideload_name]
|
18
28
|
end
|
19
29
|
|
20
|
-
def
|
21
|
-
|
30
|
+
def self.sideload_resource_class(sideload_name)
|
31
|
+
sideload_config(sideload_name)&.resource_class
|
22
32
|
end
|
23
33
|
|
24
|
-
def
|
34
|
+
def self.custom_eagerload(sideload_name)
|
35
|
+
sideload_config(sideload_name)&.custom_eagerload
|
25
36
|
end
|
26
37
|
|
27
38
|
def extra_attribute?(name)
|
28
|
-
|
39
|
+
self.class.extra_attribute?(name)
|
29
40
|
end
|
30
|
-
end
|
31
41
|
|
32
|
-
|
33
|
-
|
34
|
-
self.class.relation_resource?
|
42
|
+
def build_scope(base, query, opts = {})
|
43
|
+
scoping_class.new(base, self, query, opts)
|
35
44
|
end
|
36
45
|
|
37
|
-
def
|
38
|
-
|
46
|
+
def handle_includes(scope, includes, sorts, **opts)
|
47
|
+
includes_str = JSONAPI::IncludeDirective.new(includes, retain_rel_limit: true).to_string.split(',')
|
48
|
+
options = opts.merge(max_page_size:).merge!(authorize_scope_params)
|
49
|
+
scope.with_ordered_associations(includes_str, sorts, options)
|
39
50
|
end
|
40
51
|
|
41
52
|
def sideload_name_arr(query)
|
@@ -68,6 +79,20 @@ module Graphiti
|
|
68
79
|
raise Errors::TypecastFailed.new(self, name, value, e, type_name)
|
69
80
|
end
|
70
81
|
end
|
82
|
+
|
83
|
+
def authorize_scope_params
|
84
|
+
{}
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def scoping_class
|
90
|
+
Scope
|
91
|
+
end
|
92
|
+
|
93
|
+
def update_foreign_key(*)
|
94
|
+
true
|
95
|
+
end
|
71
96
|
end
|
72
97
|
end
|
73
98
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Graphiti
|
2
|
+
module ActiveGraph
|
3
|
+
class Scope < Graphiti::Scope
|
4
|
+
def non_applicable_for_unpaginated
|
5
|
+
%i[association_eagerload]
|
6
|
+
end
|
7
|
+
|
8
|
+
def apply_scoping(scope, opts)
|
9
|
+
opts[:query_obj] = @query
|
10
|
+
super
|
11
|
+
|
12
|
+
append_scopings(opts) unless @resource.remote?
|
13
|
+
@object
|
14
|
+
end
|
15
|
+
|
16
|
+
def append_scopings(opts)
|
17
|
+
add_scoping(:association_eagerload, Scoping::AssociationEagerLoad, opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_scoping(key, scoping_class, opts, _ = {})
|
21
|
+
@object = scoping_class.new(@resource, @query.hash, @object, opts).apply
|
22
|
+
return if non_applicable_for_unpaginated.include?(key)
|
23
|
+
@unpaginated_object = scoping_class.new(@resource, @query.hash, @unpaginated_object, opts.merge(unpaginated_query: true)).apply
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Graphiti::ActiveGraph
|
2
|
+
module Scoping
|
3
|
+
# Handles sideloading via scoping instead of sideloading query as in original jsonapi_suite
|
4
|
+
class AssociationEagerLoad < Graphiti::Scoping::Base
|
5
|
+
def custom_scope
|
6
|
+
nil
|
7
|
+
end
|
8
|
+
|
9
|
+
def apply_standard_scope
|
10
|
+
return @scope unless eagerload_associations?
|
11
|
+
if (ids = @scope.collect(&:id)).present?
|
12
|
+
@opts[:query_obj].include_hash.each_key do |key|
|
13
|
+
eagerload_association(key, ids)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
@scope
|
17
|
+
end
|
18
|
+
|
19
|
+
def eagerload_associations?
|
20
|
+
@opts[:query_obj].include_hash.present? && @resource.model.include?(ActiveGraph::Node) &&
|
21
|
+
@resource.model.associations_to_eagerload.present?
|
22
|
+
end
|
23
|
+
|
24
|
+
def eagerload_association(key, ids)
|
25
|
+
return unless @resource.model.eagerload_association?(key)
|
26
|
+
nodes = @resource.model.association_nodes(key, ids, @resource.context.send(:association_filter_params))
|
27
|
+
@scope.each { |node| node.send("#{key}=", nodes[node.id] || nil_or_empty(key)) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def nil_or_empty(key)
|
31
|
+
@resource.class.config[:sideloads][key].type == :has_one ? nil : []
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/graphiti-activegraph.rb
CHANGED
@@ -20,21 +20,23 @@ loader.ignore(File.expand_path('graphiti-activegraph.rb', __dir__))
|
|
20
20
|
loader.setup
|
21
21
|
|
22
22
|
Graphiti::Scoping::Filterable.prepend Graphiti::ActiveGraph::Scoping::Filterable
|
23
|
-
Graphiti::Resource::Persistence.prepend Graphiti::ActiveGraph::
|
24
|
-
Graphiti::Resource::Interface::ClassMethods.prepend Graphiti::ActiveGraph::
|
23
|
+
Graphiti::Resource::Persistence.prepend Graphiti::ActiveGraph::Resources::Persistence
|
24
|
+
Graphiti::Resource::Interface::ClassMethods.prepend Graphiti::ActiveGraph::Resources::Interface::ClassMethods
|
25
25
|
require 'graphiti'
|
26
26
|
Graphiti::Scoping::Filter.prepend Graphiti::ActiveGraph::Scoping::Filter
|
27
27
|
Graphiti::Util::SerializerRelationship.prepend Graphiti::ActiveGraph::Util::SerializerRelationship
|
28
28
|
Graphiti::Util::SerializerAttribute.prepend Graphiti::ActiveGraph::Util::SerializerAttribute
|
29
29
|
Graphiti::Util::RelationshipPayload.prepend Graphiti::ActiveGraph::Util::RelationshipPayload
|
30
30
|
Graphiti::Query.prepend Graphiti::ActiveGraph::Query
|
31
|
-
Graphiti::Resource.prepend Graphiti::ActiveGraph::ResourceInstanceMethods
|
32
|
-
Graphiti::Resource.extend Graphiti::ActiveGraph::Resource
|
33
31
|
Graphiti::ResourceProxy.prepend Graphiti::ActiveGraph::ResourceProxy
|
34
32
|
Graphiti::Runner.prepend Graphiti::ActiveGraph::Runner
|
35
33
|
Graphiti::Scope.prepend Graphiti::ActiveGraph::SideloadResolve
|
36
34
|
Graphiti::Configuration.include Graphiti::SidepostConfiguration
|
37
35
|
Graphiti::RequestValidators::Validator.prepend Graphiti::ActiveGraph::RequestValidators::Validator
|
38
36
|
|
37
|
+
unless RUBY_PLATFORM == 'java'
|
38
|
+
Graphiti.prepend Graphiti::ActiveGraph::Extensions::Context
|
39
|
+
end
|
40
|
+
|
39
41
|
# JSONAPI extensions
|
40
42
|
JSONAPI::Serializable::Resource.prepend Graphiti::ActiveGraph::JsonapiExt::Serializable::ResourceExt
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphiti-activegraph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hardik Joshi
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-03-21 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: graphiti
|
@@ -80,6 +79,34 @@ dependencies:
|
|
80
79
|
- - ">="
|
81
80
|
- !ruby/object:Gem::Version
|
82
81
|
version: '0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: ffaker
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: factory_bot_rails
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
83
110
|
- !ruby/object:Gem::Dependency
|
84
111
|
name: rake
|
85
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,7 +135,6 @@ dependencies:
|
|
108
135
|
- - ">="
|
109
136
|
- !ruby/object:Gem::Version
|
110
137
|
version: 3.9.0
|
111
|
-
description:
|
112
138
|
email:
|
113
139
|
- hardikjoshi1991@gmail.com
|
114
140
|
executables: []
|
@@ -119,8 +145,10 @@ files:
|
|
119
145
|
- ".gitignore"
|
120
146
|
- ".rspec"
|
121
147
|
- CHANGELOG.md
|
148
|
+
- CHANGELOG_PRE_1.0.0.md
|
122
149
|
- Gemfile
|
123
150
|
- LICENSE.txt
|
151
|
+
- README.md
|
124
152
|
- graphiti-activegraph.gemspec
|
125
153
|
- lib/graphiti-activegraph.rb
|
126
154
|
- lib/graphiti/active_graph/adapters/active_graph.rb
|
@@ -131,16 +159,23 @@ files:
|
|
131
159
|
- lib/graphiti/active_graph/adapters/active_graph/sideload.rb
|
132
160
|
- lib/graphiti/active_graph/concerns/path_relationships.rb
|
133
161
|
- lib/graphiti/active_graph/deserializer.rb
|
162
|
+
- lib/graphiti/active_graph/extensions/context.rb
|
134
163
|
- lib/graphiti/active_graph/extensions/grouping/params.rb
|
135
164
|
- lib/graphiti/active_graph/extensions/query_params.rb
|
165
|
+
- lib/graphiti/active_graph/extensions/resources/authorizationable.rb
|
166
|
+
- lib/graphiti/active_graph/extensions/resources/payload_combinable.rb
|
167
|
+
- lib/graphiti/active_graph/extensions/resources/preloadable.rb
|
168
|
+
- lib/graphiti/active_graph/extensions/resources/rel.rb
|
136
169
|
- lib/graphiti/active_graph/jsonapi_ext/serializable/resource_ext.rb
|
137
170
|
- lib/graphiti/active_graph/query.rb
|
138
171
|
- lib/graphiti/active_graph/request_validators/validator.rb
|
139
172
|
- lib/graphiti/active_graph/resource.rb
|
140
|
-
- lib/graphiti/active_graph/resource/interface.rb
|
141
|
-
- lib/graphiti/active_graph/resource/persistence.rb
|
142
173
|
- lib/graphiti/active_graph/resource_proxy.rb
|
174
|
+
- lib/graphiti/active_graph/resources/interface.rb
|
175
|
+
- lib/graphiti/active_graph/resources/persistence.rb
|
143
176
|
- lib/graphiti/active_graph/runner.rb
|
177
|
+
- lib/graphiti/active_graph/scope.rb
|
178
|
+
- lib/graphiti/active_graph/scoping/association_eager_load.rb
|
144
179
|
- lib/graphiti/active_graph/scoping/filter.rb
|
145
180
|
- lib/graphiti/active_graph/scoping/filterable.rb
|
146
181
|
- lib/graphiti/active_graph/sideload_resolve.rb
|
@@ -153,7 +188,6 @@ homepage: https://github.com/mrhardikjoshi/graphiti-activegraph
|
|
153
188
|
licenses:
|
154
189
|
- MIT
|
155
190
|
metadata: {}
|
156
|
-
post_install_message:
|
157
191
|
rdoc_options: []
|
158
192
|
require_paths:
|
159
193
|
- lib
|
@@ -168,8 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
202
|
- !ruby/object:Gem::Version
|
169
203
|
version: '0'
|
170
204
|
requirements: []
|
171
|
-
rubygems_version: 3.
|
172
|
-
signing_key:
|
205
|
+
rubygems_version: 3.6.2
|
173
206
|
specification_version: 4
|
174
207
|
summary: Easily build jsonapi.org-compatible APIs for GraphDB
|
175
208
|
test_files: []
|