graphiti-activegraph 0.1.26 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4e2e06c991422f868705fa49e812c51af9c537366fac6246ebfc882969e7bdae
4
- data.tar.gz: 7fc80649e1455f255450e00dcf6c66fe0ff889d1d74e16ebe123dc70362e8266
3
+ metadata.gz: '0928b60dbd846d64a29c21e84023b471b619e437261e1d8b77f840e5c633dd81'
4
+ data.tar.gz: 69afd454fcf50c4ffa50930de69bea8d182c5e32681c9be2c9c33b676719f102
5
5
  SHA512:
6
- metadata.gz: 3db8cee492d4ac415bddc3a44cf755cfa4f32a0b3865f90821c62a681838776d48c6e12dff4fd30fafce88f204c56884c37bc016bc4b71166fe572ec725ab1df
7
- data.tar.gz: 8d7f27a547460a725247b4b28ea629fec384f20e0255f29771c6f805e096063f8bfb5138e576f7ef7d6c7eb1acfe4cfca735940d2852dee41fee3042462ca604
6
+ metadata.gz: b6675d6ee443f716836b6ce3680597d2ee9abcb5ff5999ba8cd452d03128d3794a5f0bc663d311d99401f4549887f77347be86d0fc84430c5b5b3e869b0bcf10
7
+ data.tar.gz: 1f972ef62c9bf15ba0b0881206cb09bcb5986a8cd2f28875d703e3d372d61ce89e19cf12f049b6609416ead6d52704185f5791554e5967631d90327ef610e52a
@@ -18,20 +18,34 @@ jobs:
18
18
  strategy:
19
19
  fail-fast: false
20
20
  matrix:
21
- ruby-version: [ jruby ]
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@v3
41
+ uses: actions/setup-java@v4
42
+ if: matrix.java-version
33
43
  with:
34
44
  distribution: 'temurin'
35
- java-version: 17
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
@@ -52,5 +52,8 @@ build-iPhoneSimulator/
52
52
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
53
  .rvmrc
54
54
 
55
+ # RubyMine project files
56
+ .idea
57
+
55
58
  # Used by RuboCop. Remote config files pulled in from inherit_from directive.
56
59
  # .rubocop-https?--*
data/CHANGELOG.md CHANGED
@@ -1,69 +1,27 @@
1
- ## Unreleased
1
+ # Changelog
2
2
 
3
- -
3
+ All notable changes to this project will be documented in this file.
4
4
 
5
- ## 0.1.8 (09-06-2021)
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
- Features:
8
+ ## [Unreleased]
8
9
 
9
- - Added support for polymorphic relationship.
10
+ ## [1.0.0] - 2025-03-18
10
11
 
11
- ## 0.1.13 (21-12-2021)
12
+ ### Added
12
13
 
13
- Features:
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
- - Supports Jruby-9.3.2.0
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
- ## 0.1.14 (21-12-2021)
22
+ ---
18
23
 
19
- Features:
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
- - Adding unpaginated query to resource proxy with preloaded records. This will help in getting count on API.
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
- <!-- ### [version (DD-MM-YYYY)] -->
66
- <!-- Breaking changes:-->
67
- <!-- Features:-->
68
- <!-- Fixes:-->
69
- <!-- 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
+ [![Gem Version](https://badge.fury.io/rb/graphiti-activegraph.svg)](https://badge.fury.io/rb/graphiti-activegraph) [![Build Status](https://github.com/mrhardikjoshi/graphiti-activegraph/actions/workflows/specs.yml/badge.svg?branch=master)](https://github.com/mrhardikjoshi/graphiti-activegraph/actions?query=branch%3Amaster) [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](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.
@@ -1,36 +1,30 @@
1
- lib = File.expand_path("../lib", __FILE__)
1
+ lib = File.expand_path('../lib', __FILE__)
2
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "graphiti/active_graph/version"
3
+ require 'graphiti/active_graph/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.name = "graphiti-activegraph"
6
+ spec.name = 'graphiti-activegraph'
7
7
  spec.version = Graphiti::ActiveGraph::VERSION
8
- spec.authors = ["Hardik Joshi"]
9
- spec.email = ["hardikjoshi1991@gmail.com"]
8
+ spec.authors = ['Hardik Joshi']
9
+ spec.email = ['hardikjoshi1991@gmail.com']
10
10
 
11
- spec.summary = "Easily build jsonapi.org-compatible APIs for GraphDB"
12
- spec.homepage = "https://github.com/mrhardikjoshi/graphiti-activegraph"
13
- spec.license = "MIT"
11
+ spec.summary = 'Easily build jsonapi.org-compatible APIs for GraphDB'
12
+ spec.homepage = 'https://github.com/mrhardikjoshi/graphiti-activegraph'
13
+ spec.license = 'MIT'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
- spec.bindir = "exe"
16
+ spec.bindir = 'exe'
17
17
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
- spec.add_dependency "graphiti", ">= 1.2.0"
21
- spec.add_dependency "activegraph", "~> 12.0.0.beta.4"
22
- spec.add_dependency "activesupport", ">= 6.0"
23
- spec.add_dependency "zeitwerk"
20
+ spec.add_dependency 'graphiti', '>= 1.6.4'
21
+ spec.add_dependency 'activegraph', '>= 12.0.0.beta.5'
24
22
 
25
- spec.add_development_dependency "faraday", "~> 0.15"
26
- spec.add_development_dependency "kaminari", "~> 0.17"
27
- spec.add_development_dependency "bundler"
28
- # dependency conflict introduced during runtime
29
- # jar-dependencies is a default gem in JRuby and also a dependency in neo4j-ruby-driver
30
- spec.add_development_dependency "jar-dependencies", "~> 0.4.1"
31
- spec.add_development_dependency "rake", "~> 10.0"
32
- spec.add_development_dependency "graphiti_spec_helpers", "1.0.beta.4"
33
- spec.add_development_dependency "standard"
34
- spec.add_development_dependency "pry"
35
- spec.add_development_dependency "rspec", "~> 3.9.0"
23
+ spec.add_development_dependency 'graphiti_spec_helpers', '>= 1.0.0'
24
+ spec.add_development_dependency 'standard'
25
+ spec.add_development_dependency 'pry'
26
+ spec.add_development_dependency 'ffaker'
27
+ spec.add_development_dependency 'factory_bot_rails'
28
+ spec.add_development_dependency 'rake', '>= 10.0'
29
+ spec.add_development_dependency 'rspec', '>= 3.9.0'
36
30
  end
@@ -4,12 +4,4 @@ class Graphiti::ActiveGraph::Adapters::ActiveGraph::FunctionSideload < Graphiti:
4
4
  def association?
5
5
  false
6
6
  end
7
-
8
- def self.function_proc(&blk)
9
- self.function_proc = blk
10
- end
11
-
12
- def self.param_proc(&blk)
13
- self.param_proc = blk
14
- end
15
7
  end
@@ -1,6 +1,6 @@
1
1
  module Graphiti::ActiveGraph
2
2
  module Adapters
3
- class ActiveGraph < ::Graphiti::Adapters::Abstract
3
+ class ActiveGraph < Graphiti::Adapters::Abstract
4
4
  def self.sideloading_classes
5
5
  {
6
6
  has_many: Graphiti::ActiveGraph::Adapters::ActiveGraph::HasManySideload,
@@ -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
- module Resource
4
- def relation_resource?
5
- config[:relation_resource] || false
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 relationship_resource=(value)
9
- config[:relation_resource] = value
19
+ def self.guard_nil_id!(params)
10
20
  end
11
21
 
12
- def with_preloaded_obj(obj, params)
13
- id = params[:data].try(:[], :id) || params.delete(:id)
14
- params[:filter] ||= {}
15
- params[:filter][:id] = id if id
22
+ def self.extra_attribute?(name)
23
+ extra_attributes.has_key?(name)
24
+ end
16
25
 
17
- build(params, nil, raise_on_missing: false, preloaded: obj)
26
+ def self.sideload_config(sideload_name)
27
+ config[:sideloads][sideload_name]
18
28
  end
19
29
 
20
- def all_with_preloaded(obj_arr, params)
21
- build(params, nil, single: false, raise_on_missing: false, preloaded: obj_arr)
30
+ def self.sideload_resource_class(sideload_name)
31
+ sideload_config(sideload_name)&.resource_class
22
32
  end
23
33
 
24
- def guard_nil_id!(params)
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
- extra_attributes.has_key?(name)
39
+ self.class.extra_attribute?(name)
29
40
  end
30
- end
31
41
 
32
- module ResourceInstanceMethods
33
- def relation_resource?
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 extra_attribute?(name)
38
- self.class.extra_attribute?(name)
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
@@ -26,6 +26,8 @@ module Graphiti::ActiveGraph
26
26
  @single ? data_for_preloaded_record : data_for_preloaded_records
27
27
  end
28
28
 
29
+ alias_method :resolve_data, :data
30
+
29
31
  def data_for_preloaded_record
30
32
  @preloaded = @preloaded.is_a?(Array) ? @preloaded[0] : @preloaded
31
33
  @resource.decorate_record(@preloaded)
@@ -1,10 +1,10 @@
1
1
  module Graphiti::ActiveGraph
2
- module Resource
2
+ module Resources
3
3
  module Interface
4
4
  extend ActiveSupport::Concern
5
5
  class_methods do
6
6
  def build(params, base_scope = nil, opts = {})
7
- validate!(params)
7
+ validate_request!(params)
8
8
  runner = ::Graphiti::Runner.new(self, params)
9
9
  runner.proxy(base_scope, { single: true, raise_on_missing: true }.merge(opts) )
10
10
  end
@@ -1,5 +1,5 @@
1
1
  module Graphiti::ActiveGraph
2
- module Resource
2
+ module Resources
3
3
  module Persistence
4
4
  def update(update_params, meta = nil)
5
5
  model_instance = nil
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Graphiti
2
2
  module ActiveGraph
3
- VERSION = '0.1.26'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  end
@@ -3,6 +3,7 @@
3
3
  module Graphiti
4
4
  module SidepostConfiguration
5
5
  extend ActiveSupport::Concern
6
+
6
7
  included do
7
8
  attr_accessor :allow_sidepost
8
9
  end
@@ -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::Resource::Persistence
24
- Graphiti::Resource::Interface::ClassMethods.prepend Graphiti::ActiveGraph::Resource::Interface::ClassMethods
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,106 +1,63 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphiti-activegraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.26
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-01-13 00:00:00.000000000 Z
10
+ date: 2025-03-21 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
13
+ name: graphiti
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 1.2.0
19
- name: graphiti
18
+ version: 1.6.4
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: 1.2.0
25
+ version: 1.6.4
27
26
  - !ruby/object:Gem::Dependency
28
- requirement: !ruby/object:Gem::Requirement
29
- requirements:
30
- - - "~>"
31
- - !ruby/object:Gem::Version
32
- version: 12.0.0.beta.4
33
27
  name: activegraph
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 12.0.0.beta.4
41
- - !ruby/object:Gem::Dependency
42
28
  requirement: !ruby/object:Gem::Requirement
43
29
  requirements:
44
30
  - - ">="
45
31
  - !ruby/object:Gem::Version
46
- version: '6.0'
47
- name: activesupport
32
+ version: 12.0.0.beta.5
48
33
  type: :runtime
49
34
  prerelease: false
50
35
  version_requirements: !ruby/object:Gem::Requirement
51
36
  requirements:
52
37
  - - ">="
53
38
  - !ruby/object:Gem::Version
54
- version: '6.0'
39
+ version: 12.0.0.beta.5
55
40
  - !ruby/object:Gem::Dependency
41
+ name: graphiti_spec_helpers
56
42
  requirement: !ruby/object:Gem::Requirement
57
43
  requirements:
58
44
  - - ">="
59
45
  - !ruby/object:Gem::Version
60
- version: '0'
61
- name: zeitwerk
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - "~>"
73
- - !ruby/object:Gem::Version
74
- version: '0.15'
75
- name: faraday
46
+ version: 1.0.0
76
47
  type: :development
77
48
  prerelease: false
78
49
  version_requirements: !ruby/object:Gem::Requirement
79
50
  requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '0.15'
83
- - !ruby/object:Gem::Dependency
84
- requirement: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '0.17'
89
- name: kaminari
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
51
+ - - ">="
95
52
  - !ruby/object:Gem::Version
96
- version: '0.17'
53
+ version: 1.0.0
97
54
  - !ruby/object:Gem::Dependency
55
+ name: standard
98
56
  requirement: !ruby/object:Gem::Requirement
99
57
  requirements:
100
58
  - - ">="
101
59
  - !ruby/object:Gem::Version
102
60
  version: '0'
103
- name: bundler
104
61
  type: :development
105
62
  prerelease: false
106
63
  version_requirements: !ruby/object:Gem::Requirement
@@ -109,54 +66,40 @@ dependencies:
109
66
  - !ruby/object:Gem::Version
110
67
  version: '0'
111
68
  - !ruby/object:Gem::Dependency
69
+ name: pry
112
70
  requirement: !ruby/object:Gem::Requirement
113
71
  requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: 0.4.1
117
- name: jar-dependencies
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: 0.4.1
125
- - !ruby/object:Gem::Dependency
126
- requirement: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
72
+ - - ">="
129
73
  - !ruby/object:Gem::Version
130
- version: '10.0'
131
- name: rake
74
+ version: '0'
132
75
  type: :development
133
76
  prerelease: false
134
77
  version_requirements: !ruby/object:Gem::Requirement
135
78
  requirements:
136
- - - "~>"
79
+ - - ">="
137
80
  - !ruby/object:Gem::Version
138
- version: '10.0'
81
+ version: '0'
139
82
  - !ruby/object:Gem::Dependency
83
+ name: ffaker
140
84
  requirement: !ruby/object:Gem::Requirement
141
85
  requirements:
142
- - - '='
86
+ - - ">="
143
87
  - !ruby/object:Gem::Version
144
- version: 1.0.beta.4
145
- name: graphiti_spec_helpers
88
+ version: '0'
146
89
  type: :development
147
90
  prerelease: false
148
91
  version_requirements: !ruby/object:Gem::Requirement
149
92
  requirements:
150
- - - '='
93
+ - - ">="
151
94
  - !ruby/object:Gem::Version
152
- version: 1.0.beta.4
95
+ version: '0'
153
96
  - !ruby/object:Gem::Dependency
97
+ name: factory_bot_rails
154
98
  requirement: !ruby/object:Gem::Requirement
155
99
  requirements:
156
100
  - - ">="
157
101
  - !ruby/object:Gem::Version
158
102
  version: '0'
159
- name: standard
160
103
  type: :development
161
104
  prerelease: false
162
105
  version_requirements: !ruby/object:Gem::Requirement
@@ -165,34 +108,33 @@ dependencies:
165
108
  - !ruby/object:Gem::Version
166
109
  version: '0'
167
110
  - !ruby/object:Gem::Dependency
111
+ name: rake
168
112
  requirement: !ruby/object:Gem::Requirement
169
113
  requirements:
170
114
  - - ">="
171
115
  - !ruby/object:Gem::Version
172
- version: '0'
173
- name: pry
116
+ version: '10.0'
174
117
  type: :development
175
118
  prerelease: false
176
119
  version_requirements: !ruby/object:Gem::Requirement
177
120
  requirements:
178
121
  - - ">="
179
122
  - !ruby/object:Gem::Version
180
- version: '0'
123
+ version: '10.0'
181
124
  - !ruby/object:Gem::Dependency
125
+ name: rspec
182
126
  requirement: !ruby/object:Gem::Requirement
183
127
  requirements:
184
- - - "~>"
128
+ - - ">="
185
129
  - !ruby/object:Gem::Version
186
130
  version: 3.9.0
187
- name: rspec
188
131
  type: :development
189
132
  prerelease: false
190
133
  version_requirements: !ruby/object:Gem::Requirement
191
134
  requirements:
192
- - - "~>"
135
+ - - ">="
193
136
  - !ruby/object:Gem::Version
194
137
  version: 3.9.0
195
- description:
196
138
  email:
197
139
  - hardikjoshi1991@gmail.com
198
140
  executables: []
@@ -203,8 +145,10 @@ files:
203
145
  - ".gitignore"
204
146
  - ".rspec"
205
147
  - CHANGELOG.md
148
+ - CHANGELOG_PRE_1.0.0.md
206
149
  - Gemfile
207
150
  - LICENSE.txt
151
+ - README.md
208
152
  - graphiti-activegraph.gemspec
209
153
  - lib/graphiti-activegraph.rb
210
154
  - lib/graphiti/active_graph/adapters/active_graph.rb
@@ -215,16 +159,23 @@ files:
215
159
  - lib/graphiti/active_graph/adapters/active_graph/sideload.rb
216
160
  - lib/graphiti/active_graph/concerns/path_relationships.rb
217
161
  - lib/graphiti/active_graph/deserializer.rb
162
+ - lib/graphiti/active_graph/extensions/context.rb
218
163
  - lib/graphiti/active_graph/extensions/grouping/params.rb
219
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
220
169
  - lib/graphiti/active_graph/jsonapi_ext/serializable/resource_ext.rb
221
170
  - lib/graphiti/active_graph/query.rb
222
171
  - lib/graphiti/active_graph/request_validators/validator.rb
223
172
  - lib/graphiti/active_graph/resource.rb
224
- - lib/graphiti/active_graph/resource/interface.rb
225
- - lib/graphiti/active_graph/resource/persistence.rb
226
173
  - lib/graphiti/active_graph/resource_proxy.rb
174
+ - lib/graphiti/active_graph/resources/interface.rb
175
+ - lib/graphiti/active_graph/resources/persistence.rb
227
176
  - lib/graphiti/active_graph/runner.rb
177
+ - lib/graphiti/active_graph/scope.rb
178
+ - lib/graphiti/active_graph/scoping/association_eager_load.rb
228
179
  - lib/graphiti/active_graph/scoping/filter.rb
229
180
  - lib/graphiti/active_graph/scoping/filterable.rb
230
181
  - lib/graphiti/active_graph/sideload_resolve.rb
@@ -237,7 +188,6 @@ homepage: https://github.com/mrhardikjoshi/graphiti-activegraph
237
188
  licenses:
238
189
  - MIT
239
190
  metadata: {}
240
- post_install_message:
241
191
  rdoc_options: []
242
192
  require_paths:
243
193
  - lib
@@ -252,8 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
252
202
  - !ruby/object:Gem::Version
253
203
  version: '0'
254
204
  requirements: []
255
- rubygems_version: 3.3.26
256
- signing_key:
205
+ rubygems_version: 3.6.2
257
206
  specification_version: 4
258
207
  summary: Easily build jsonapi.org-compatible APIs for GraphDB
259
208
  test_files: []