activegraph 11.4.0 → 11.5.0.beta.1

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +12 -1
  3. data/Gemfile +0 -4
  4. data/activegraph.gemspec +5 -6
  5. data/lib/active_graph/attribute_set.rb +0 -4
  6. data/lib/active_graph/base.rb +0 -3
  7. data/lib/active_graph/config.rb +0 -1
  8. data/lib/active_graph/core/instrumentable.rb +0 -5
  9. data/lib/active_graph/core/querable.rb +0 -5
  10. data/lib/active_graph/core/query.rb +4 -7
  11. data/lib/active_graph/core/query_ext.rb +1 -1
  12. data/lib/active_graph/core/record.rb +0 -5
  13. data/lib/active_graph/core/result.rb +5 -0
  14. data/lib/active_graph/core/wrappable.rb +1 -1
  15. data/lib/active_graph/lazy_attribute_hash.rb +0 -2
  16. data/lib/active_graph/migration.rb +0 -3
  17. data/lib/active_graph/migrations/helpers.rb +0 -7
  18. data/lib/active_graph/migrations/runner.rb +0 -4
  19. data/lib/active_graph/migrations.rb +0 -8
  20. data/lib/active_graph/model_schema.rb +0 -1
  21. data/lib/active_graph/node/has_n/association.rb +0 -3
  22. data/lib/active_graph/node/has_n.rb +5 -1
  23. data/lib/active_graph/node/labels.rb +1 -3
  24. data/lib/active_graph/node/orm_adapter.rb +0 -6
  25. data/lib/active_graph/node/query/query_proxy_methods_of_mass_updating.rb +1 -0
  26. data/lib/active_graph/node/scope.rb +4 -43
  27. data/lib/active_graph/node/wrapping.rb +52 -0
  28. data/lib/active_graph/node.rb +1 -0
  29. data/lib/active_graph/railtie.rb +11 -4
  30. data/lib/active_graph/relationship/property.rb +0 -2
  31. data/lib/active_graph/relationship/wrapping.rb +26 -0
  32. data/lib/active_graph/shared/attributes.rb +3 -2
  33. data/lib/active_graph/shared/node_query_factory.rb +15 -0
  34. data/lib/active_graph/shared/persistence.rb +1 -1
  35. data/lib/active_graph/shared/query_factory.rb +0 -60
  36. data/lib/active_graph/shared/rel_query_factory.rb +47 -0
  37. data/lib/active_graph/shared/type_converters.rb +0 -6
  38. data/lib/active_graph/tasks/migration.rake +0 -4
  39. data/lib/active_graph/timestamps.rb +0 -3
  40. data/lib/active_graph/transactions.rb +4 -0
  41. data/lib/active_graph/version.rb +1 -1
  42. data/lib/active_graph.rb +36 -119
  43. data/lib/rails/generators/active_graph/migration/migration_generator.rb +4 -5
  44. data/lib/rails/generators/active_graph/model/model_generator.rb +4 -5
  45. data/lib/rails/generators/active_graph/upgrade_v8/upgrade_v8_generator.rb +4 -5
  46. data/lib/rails/generators/{active_graph_generator.rb → migration_helper.rb} +2 -20
  47. data/lib/rails/generators/source_path_helper.rb +10 -0
  48. metadata +27 -34
  49. data/lib/active_graph/core.rb +0 -14
  50. data/lib/active_graph/node/node_wrapper.rb +0 -54
  51. data/lib/active_graph/relationship/rel_wrapper.rb +0 -31
  52. data/lib/active_graph/wrapper.rb +0 -4
  53. /data/lib/active_graph/{errors.rb → error.rb} +0 -0
  54. /data/lib/active_graph/node/query/{query_proxy_link.rb → query_proxy/link.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f068da2126bbed4301cf9fb15c34a708ef7f7a152afbfe42af5482237a041f0d
4
- data.tar.gz: 0c87c4c2082a2e999ac8e0ff165e0cdbffe875f7f2eae407ea31f3f119d46a5f
3
+ metadata.gz: c217d68abf8f640ef01f10e2d7a5b96c6fe7b6f3c4499d24da58718a90646acc
4
+ data.tar.gz: d8bcda3316fd7cdc1422eb47b186f6eb7d853752d138f014e53a0e425c2f3e4f
5
5
  SHA512:
6
- metadata.gz: 5c12b0fc53c6bb04d661ec6c1669843e3c59d2ce00a9c7ea909d49b87ba7ef7b4c58ba2196d2c880c70da4ed727d14851fa27a15cf948125e91ee7670a23ff9d
7
- data.tar.gz: e0dda99c677170338a7a470d00660fa20528e272452ee81a58722d055af969f0951e3344e0961e3b5ec49b6e0e316527dc0deab5f0ce01fe3dda0c029310ee01
6
+ metadata.gz: fa79ae2d367a183fb0a5a26363f352d15767540288ae080558fc876854100ecf01815fb76be5460d1f638c3c1a8799a5b44f09e7ce5d0efc8faa8a74baf9c187
7
+ data.tar.gz: e39a318db8e56067cffbd7ba216d3951184124cb36b48da420334475472d63d17bff7d70027d4d7a9e495d7cb4cb7d4dd8b27b9a4c3bf44e265b24503802b2fd
data/CHANGELOG.md CHANGED
@@ -3,10 +3,21 @@ All notable changes to this project will be documented in this file.
3
3
  This file should follow the standards specified on [http://keepachangelog.com/]
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
- ## [11.4.0] 2023-02-12
6
+ ## [11.5.0.beta.1] 2023-12-29
7
+
8
+ ## Added
9
+
10
+ - migrated to zeitwerk
11
+ - rails 7.1 support
7
12
 
8
13
  ## Fixed
9
14
 
15
+ - caching of has one relationships
16
+
17
+ ## [11.4.0] 2023-12-02
18
+
19
+ ## Added
20
+
10
21
  - Added support for cypher UNION
11
22
 
12
23
  ## [11.3.1] 2023-02-12
data/Gemfile CHANGED
@@ -2,10 +2,6 @@ source 'http://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- # gem 'neo4j-ruby-driver', path: '../neo4j-ruby-driver'
6
-
7
- gem 'listen', '< 3.1'
8
-
9
5
  active_model_version = ENV['ACTIVE_MODEL_VERSION']
10
6
  gem 'activemodel', "~> #{active_model_version}" if active_model_version&.length&.positive?
11
7
 
data/activegraph.gemspec CHANGED
@@ -30,11 +30,10 @@ DESCRIPTION
30
30
  'bug_tracker_uri' => 'https://github.com/neo4jrb/activegraph/issues'
31
31
  }
32
32
 
33
- s.add_dependency('activemodel', '>= 4.0')
34
- s.add_dependency('activesupport', '>= 4.0')
33
+ s.add_dependency('activemodel', '>= 7')
35
34
  s.add_dependency('i18n', '!= 1.8.8') # https://github.com/jruby/jruby/issues/6547
36
- s.add_dependency('neo4j-ruby-driver', '>= 4.4.1')
37
- s.add_dependency('orm_adapter', '~> 0.5.0')
35
+ s.add_dependency('neo4j-ruby-driver', '>= 4.4.1', '< 5')
36
+ s.add_dependency('orm_adapter', '>= 0.5.0')
38
37
  s.add_dependency('sorted_set')
39
38
  s.add_development_dependency('guard')
40
39
  s.add_development_dependency('guard-rspec')
@@ -42,10 +41,10 @@ DESCRIPTION
42
41
  s.add_development_dependency('neo4j-rake_tasks', '>= 0.3.0')
43
42
  s.add_development_dependency('os')
44
43
  s.add_development_dependency('pry')
45
- s.add_development_dependency('railties', '>= 4.0')
44
+ s.add_development_dependency('railties', '>= 7')
46
45
  s.add_development_dependency('rake')
47
46
  s.add_development_dependency('rubocop', '>= 0.56.0')
48
47
  s.add_development_dependency('yard')
49
48
  s.add_development_dependency('dryspec')
50
- s.add_development_dependency('rspec', '< 3.10') # Cannot proxy frozen objects
49
+ s.add_development_dependency('rspec', '>= 3.10')
51
50
  end
@@ -1,7 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_model/attribute_set'
4
-
5
1
  module ActiveGraph
6
2
  class AttributeSet < ActiveModel::AttributeSet
7
3
  def initialize(attr_hash, attr_list)
@@ -1,6 +1,3 @@
1
- require 'active_graph/core/querable'
2
- require 'active_graph/core/schema'
3
-
4
1
  module ActiveGraph
5
2
  # To contain any base login for Node/Relationship which
6
3
  # is external to the main classes
@@ -26,7 +26,6 @@ module ActiveGraph
26
26
 
27
27
  # @return [Hash] the default file loaded by yaml
28
28
  def defaults
29
- require 'yaml'
30
29
  @defaults ||= ActiveSupport::HashWithIndifferentAccess.new(YAML.load_file(default_file))
31
30
  end
32
31
 
@@ -1,8 +1,3 @@
1
- require 'active_support/concern'
2
- require 'active_support/notifications'
3
- require 'active_graph/ansi'
4
- require 'active_graph/core/logging'
5
-
6
1
  module ActiveGraph
7
2
  module Core
8
3
  module Instrumentable
@@ -1,8 +1,3 @@
1
- require 'active_graph/core/instrumentable'
2
- require 'active_graph/transaction'
3
- require 'active_graph/core/query_builder'
4
- require 'active_graph/core/record'
5
-
6
1
  module ActiveGraph
7
2
  module Core
8
3
  module Querable
@@ -1,7 +1,3 @@
1
- require 'active_graph/core/query_clauses'
2
- require 'active_graph/core/query_find_in_batches'
3
- require 'active_support/notifications'
4
-
5
1
  module ActiveGraph
6
2
  module Core
7
3
  # Allows for generation of cypher queries via ruby method calls (inspired by ActiveRecord / arel syntax)
@@ -15,9 +11,9 @@ module ActiveGraph
15
11
  class Query
16
12
  include ActiveGraph::Core::QueryClauses
17
13
  include ActiveGraph::Core::QueryFindInBatches
14
+ include QueryExt
18
15
  DEFINED_CLAUSES = {}
19
16
 
20
-
21
17
  attr_accessor :clauses
22
18
 
23
19
  class Parameters
@@ -247,7 +243,7 @@ module ActiveGraph
247
243
  neo_id = (node_object.respond_to?(:neo_id) ? node_object.neo_id : node_object)
248
244
 
249
245
  match_method = optional_match ? :optional_match : :match
250
- query.send(match_method, variable).where(variable => {neo_id: neo_id})
246
+ query.send(match_method, variable).where(variable => { neo_id: })
251
247
  end
252
248
  end
253
249
 
@@ -271,7 +267,6 @@ module ActiveGraph
271
267
  # @return [Array]
272
268
  # @raise [ActiveGraph::Server::CypherResponse::ResponseError] Raises errors from neo4j server
273
269
 
274
-
275
270
  # Executes a query without returning the result
276
271
  # @return [Boolean] true if successful
277
272
  # @raise [ActiveGraph::Server::CypherResponse::ResponseError] Raises errors from neo4j server
@@ -318,6 +313,7 @@ module ActiveGraph
318
313
  # @return [String] Resulting cypher query string
319
314
  EMPTY = ' '
320
315
  NEWLINE = "\n"
316
+
321
317
  def to_cypher(options = {})
322
318
  join_string = options[:pretty] ? NEWLINE : EMPTY
323
319
 
@@ -334,6 +330,7 @@ module ActiveGraph
334
330
  cypher_string = "CYPHER #{@options[:parser]} #{cypher_string}" if @options[:parser]
335
331
  cypher_string.tap(&:strip!)
336
332
  end
333
+
337
334
  alias cypher to_cypher
338
335
 
339
336
  def pretty_cypher
@@ -1,6 +1,6 @@
1
1
  module ActiveGraph
2
2
  module Core
3
- class Query
3
+ module QueryExt
4
4
  # Creates a ActiveGraph::Node::Query::QueryProxy object that builds off of a Core::Query object.
5
5
  #
6
6
  # @param [Class] model An Node model to be used as the start of a new QueryuProxy chain
@@ -1,8 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_graph/core/result'
4
- require 'active_support/core_ext/module/attribute_accessors'
5
-
6
1
  module ActiveGraph
7
2
  module Core
8
3
  module Record
@@ -16,6 +16,11 @@ module ActiveGraph
16
16
  @records&.each(&block) || super
17
17
  end
18
18
 
19
+ ## To avoid to_a on Neo4j::Driver::Result as that one does not call the above block
20
+ def to_a
21
+ map.to_a
22
+ end
23
+
19
24
  def store
20
25
  return if @records
21
26
  keys
@@ -8,7 +8,7 @@ module ActiveGraph
8
8
  end
9
9
 
10
10
  class_methods do
11
- def wrapper_callback(proc)
11
+ def wrapper_callback(&proc)
12
12
  fail 'Callback already specified!' if @wrapper_callback
13
13
  @wrapper_callback = proc
14
14
  end
@@ -1,5 +1,3 @@
1
- require 'active_model/attribute_set'
2
-
3
1
  module ActiveGraph
4
2
  class LazyAttributeHash < ActiveModel::LazyAttributeHash
5
3
  def initialize(values, attr_list)
@@ -1,6 +1,3 @@
1
- require 'benchmark'
2
- require 'active_graph/migrations/helpers/id_property'
3
-
4
1
  module ActiveGraph
5
2
  class Migration
6
3
  def migrate
@@ -1,14 +1,7 @@
1
- require 'benchmark'
2
-
3
1
  module ActiveGraph
4
2
  module Migrations
5
3
  module Helpers
6
4
  extend ActiveSupport::Concern
7
- extend ActiveSupport::Autoload
8
-
9
- autoload :Schema
10
- autoload :IdProperty
11
- autoload :Relationships
12
5
 
13
6
  PROPERTY_ALREADY_DEFINED = 'Property `%{new_property}` is already defined in `%{label}`. '\
14
7
  'To overwrite, call `remove_property(:%{label}, :%{new_property})` before this method.'.freeze
@@ -1,7 +1,3 @@
1
- # frozen_string_literal: true
2
-
3
- require 'sorted_set'
4
-
5
1
  module ActiveGraph
6
2
  module Migrations
7
3
  class Runner
@@ -1,13 +1,5 @@
1
1
  module ActiveGraph
2
2
  module Migrations
3
- extend ActiveSupport::Autoload
4
- autoload :Helpers
5
- autoload :MigrationFile
6
- autoload :Base
7
- autoload :Runner
8
- autoload :SchemaMigration
9
- autoload :CheckPending
10
-
11
3
  class << self
12
4
  def check_for_pending_migrations!
13
5
  return if ActiveGraph::Config.configuration['skip_migration_check']
@@ -1,4 +1,3 @@
1
- require 'set'
2
1
  module ActiveGraph
3
2
  # This is here to support the removed functionality of being able to
4
3
  # defined indexes and constraints on models
@@ -1,6 +1,3 @@
1
- require 'active_support/inflector/inflections'
2
- require 'active_graph/class_arguments'
3
-
4
1
  module ActiveGraph
5
2
  module Node
6
3
  module HasN
@@ -111,13 +111,17 @@ module ActiveGraph::Node
111
111
 
112
112
  def add_to_cache(object, rel = nil)
113
113
  (@cached_rels ||= []) << rel if rel
114
- (@cached_result ||= []).tap { |results| results << object if object && !results.include?(object) }
114
+ (@cached_result ||= []).tap { |results| results << object if !results.include?(object) } if object
115
115
  end
116
116
 
117
117
  def rels
118
118
  @cached_rels || super.tap { |rels| rels.each { |rel| add_to_cache(nil, rel) } }
119
119
  end
120
120
 
121
+ def rel
122
+ rels.first
123
+ end
124
+
121
125
  def cache_query_proxy_result
122
126
  (result_cache_proc_cache || @query_proxy).to_a.tap { |result| cache_result(result) }
123
127
  end
@@ -1,5 +1,3 @@
1
- require 'active_graph/core/label'
2
-
3
1
  module ActiveGraph
4
2
  module Node
5
3
  # Provides a mapping between neo4j labels and Ruby classes
@@ -76,7 +74,7 @@ module ActiveGraph
76
74
 
77
75
  def self.clear_wrapped_models
78
76
  MODELS_FOR_LABELS_CACHE.clear
79
- ActiveGraph::NodeWrapping::CONSTANTS_FOR_LABELS_CACHE.clear
77
+ ActiveGraph::Node::Wrapping::CONSTANTS_FOR_LABELS_CACHE.clear
80
78
  end
81
79
 
82
80
  module ClassMethods
@@ -1,11 +1,5 @@
1
- require 'orm_adapter'
2
-
3
1
  module ActiveGraph
4
2
  module Node
5
- module ClassMethods
6
- include OrmAdapter::ToAdapter
7
- end
8
-
9
3
  class OrmAdapter < ::OrmAdapter::Base
10
4
  module ClassMethods
11
5
  include ActiveModel::Callbacks
@@ -51,6 +51,7 @@ module ActiveGraph
51
51
  def replace_with(node_or_nodes)
52
52
  node_or_nodes = Array(node_or_nodes).map { |arg| arg.is_a?(ActiveGraph::Node) ? arg : @model.find(arg) }
53
53
  original_ids = self.pluck(:id)
54
+ ActiveGraph::Base.lock_node(start_object) unless start_object.new_record?
54
55
  delete_rels_for_nodes(original_ids, node_or_nodes.collect(&:id))
55
56
  add_rels(node_or_nodes, original_ids)
56
57
  end
@@ -1,9 +1,11 @@
1
- require 'active_support/per_thread_registry'
2
-
3
1
  module ActiveGraph::Node
4
2
  module Scope
5
3
  extend ActiveSupport::Concern
6
4
 
5
+ included do
6
+ thread_mattr_accessor :current_scope
7
+ end
8
+
7
9
  module ClassMethods
8
10
  # Similar to ActiveRecord scope
9
11
  #
@@ -86,14 +88,6 @@ module ActiveGraph::Node
86
88
  end
87
89
  end
88
90
 
89
- def current_scope #:nodoc:
90
- ScopeRegistry.value_for(:current_scope, base_class.to_s)
91
- end
92
-
93
- def current_scope=(scope) #:nodoc:
94
- ScopeRegistry.set_value_for(:current_scope, base_class.to_s, scope)
95
- end
96
-
97
91
  def all(new_var = nil)
98
92
  var = new_var || (current_scope ? current_scope.node_identity : :n)
99
93
  if current_scope
@@ -139,38 +133,5 @@ module ActiveGraph::Node
139
133
  @query_proxy_or_target ||= @query_proxy || @target
140
134
  end
141
135
  end
142
-
143
-
144
- # Stolen from ActiveRecord
145
- # https://github.com/rails/rails/blob/08754f12e65a9ec79633a605e986d0f1ffa4b251/activerecord/lib/active_record/scoping.rb#L57
146
- class ScopeRegistry # :nodoc:
147
- extend ActiveSupport::PerThreadRegistry
148
-
149
- VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope]
150
-
151
- def initialize
152
- @registry = Hash.new { |hash, key| hash[key] = {} }
153
- end
154
-
155
- # Obtains the value for a given +scope_name+ and +variable_name+.
156
- def value_for(scope_type, variable_name)
157
- raise_invalid_scope_type!(scope_type)
158
- @registry[scope_type][variable_name]
159
- end
160
-
161
- # Sets the +value+ for a given +scope_type+ and +variable_name+.
162
- def set_value_for(scope_type, variable_name, value)
163
- raise_invalid_scope_type!(scope_type)
164
- @registry[scope_type][variable_name] = value
165
- end
166
-
167
- private
168
-
169
- def raise_invalid_scope_type!(scope_type)
170
- return if VALID_SCOPE_TYPES.include?(scope_type)
171
-
172
- fail ArgumentError, "Invalid scope type '#{scope_type}' sent to the registry. Scope types must be included in VALID_SCOPE_TYPES"
173
- end
174
- end
175
136
  end
176
137
  end
@@ -0,0 +1,52 @@
1
+ module ActiveGraph
2
+ module Node
3
+ module Wrapping
4
+ # Only load classes once for performance
5
+ CONSTANTS_FOR_LABELS_CACHE = {}
6
+
7
+ class << self
8
+ def wrapper(node)
9
+ found_class = class_to_wrap(node.labels)
10
+ return node unless found_class
11
+
12
+ found_class.new.tap do |wrapped_node|
13
+ wrapped_node.init_on_load(node, node.properties)
14
+ end
15
+ end
16
+
17
+ def class_to_wrap(labels)
18
+ load_classes_from_labels(labels)
19
+ ActiveGraph::Node::Labels.model_for_labels(labels).tap do |model_class|
20
+ populate_constants_for_labels_cache(model_class, labels)
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def load_classes_from_labels(labels)
27
+ labels.each { |label| constant_for_label(label) }
28
+ end
29
+
30
+ def constant_for_label(label)
31
+ CONSTANTS_FOR_LABELS_CACHE[label] ||= constantized_label(label)
32
+ end
33
+
34
+ def constantized_label(label)
35
+ "#{association_model_namespace}::#{label}".constantize
36
+ rescue NameError, LoadError
37
+ nil
38
+ end
39
+
40
+ def populate_constants_for_labels_cache(model_class, labels)
41
+ labels.each do |label|
42
+ CONSTANTS_FOR_LABELS_CACHE[label] ||= model_class
43
+ end
44
+ end
45
+
46
+ def association_model_namespace
47
+ ActiveGraph::Config.association_model_namespace_string
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -66,6 +66,7 @@ module ActiveGraph
66
66
  end
67
67
 
68
68
  module ClassMethods
69
+ include ::OrmAdapter::ToAdapter
69
70
  def nodeify(object)
70
71
  if object.is_a?(::ActiveGraph::Node) || object.nil?
71
72
  object
@@ -1,9 +1,16 @@
1
- require 'active_support/notifications'
2
- require 'rails/railtie'
3
- # Need the action_dispatch railtie to have action_dispatch.rescue_responses initialized correctly
4
- require 'action_dispatch/railtie'
5
1
  require 'active_graph'
6
2
 
3
+ if defined?(Rails)
4
+ # Need the action_dispatch railtie to have action_dispatch.rescue_responses initialized correctly
5
+ require 'action_dispatch/railtie'
6
+ require 'rails/generators'
7
+ require 'rails/generators/active_model'
8
+ require 'rails/generators/named_base'
9
+ require 'rails/railtie'
10
+ require File.expand_path('../rails/generators/migration_helper.rb', __dir__)
11
+ Rails::Generators::GeneratedAttribute.include ActiveGraph::Generators::GeneratedAttribute
12
+ end
13
+
7
14
  module ActiveGraph
8
15
  class Railtie < ::Rails::Railtie
9
16
  def empty_config
@@ -1,5 +1,3 @@
1
- require 'active_graph/class_arguments'
2
-
3
1
  module ActiveGraph::Relationship
4
2
  module Property
5
3
  extend ActiveSupport::Concern
@@ -0,0 +1,26 @@
1
+ module ActiveGraph
2
+ module Relationship
3
+ module Wrapping
4
+ class << self
5
+ def wrapper(rel)
6
+ rel.properties.symbolize_keys!
7
+ begin
8
+ most_concrete_class = class_from_type(rel.type).constantize
9
+ return rel unless most_concrete_class < ActiveGraph::Relationship
10
+ most_concrete_class.new
11
+ rescue NameError => e
12
+ raise e unless e.message =~ /(uninitialized|wrong) constant/
13
+
14
+ return rel
15
+ end.tap do |wrapped_rel|
16
+ wrapped_rel.init_on_load(rel, rel.start_node_id, rel.end_node_id, rel.type)
17
+ end
18
+ end
19
+
20
+ def class_from_type(type)
21
+ ActiveGraph::Relationship::Types::WRAPPED_CLASSES[type] || ActiveGraph::Relationship::Types::WRAPPED_CLASSES[type] = type.to_s.downcase.camelize
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -18,9 +18,10 @@ module ActiveGraph::Shared
18
18
 
19
19
  # Methods deprecated on the Object class which can be safely overridden
20
20
  DEPRECATED_OBJECT_METHODS = %w(id type)
21
+ ATTRIBUTES_METHOD_PATTERNS = Gem::Requirement.create('>= 7.1').satisfied_by?(Gem.loaded_specs["activesupport"].version) ? :attribute_method_patterns : :attribute_method_matchers
21
22
 
22
23
  included do
23
- attribute_method_suffix '' if attribute_method_matchers.none? { |matcher| matcher.prefix == '' && matcher.suffix == '' }
24
+ attribute_method_suffix '' if send(ATTRIBUTES_METHOD_PATTERNS).none? { |matcher| matcher.prefix == '' && matcher.suffix == '' }
24
25
  attribute_method_suffix '='
25
26
  attribute_method_suffix '?'
26
27
  end
@@ -204,7 +205,7 @@ module ActiveGraph::Shared
204
205
 
205
206
  # Expand an attribute name into its generated methods names
206
207
  def attribute_methods(name)
207
- attribute_method_matchers.map { |matcher| matcher.method_name name }
208
+ send(ATTRIBUTES_METHOD_PATTERNS).map { |matcher| matcher.method_name name }
208
209
  end
209
210
 
210
211
  # Ruby inherited hook to assign superclass attributes to subclasses
@@ -0,0 +1,15 @@
1
+ module ActiveGraph::Shared
2
+ class NodeQueryFactory < QueryFactory
3
+ protected
4
+
5
+ def match_string
6
+ "(#{identifier})"
7
+ end
8
+
9
+ def create_query
10
+ return match_query if graph_object.persisted?
11
+ labels = graph_object.labels_for_create.map { |l| ":`#{l}`" }.join
12
+ base_query.create("(#{identifier}#{labels} $#{identifier}_params)").params(identifier_params => graph_object.props_for_create)
13
+ end
14
+ end
15
+ end
@@ -217,7 +217,7 @@ module ActiveGraph::Shared
217
217
  if self.new_record?
218
218
  "#{model_cache_key}/new"
219
219
  elsif self.respond_to?(:updated_at) && !self.updated_at.blank?
220
- "#{model_cache_key}/#{neo_id}-#{self.updated_at.utc.to_s(:number)}"
220
+ "#{model_cache_key}/#{neo_id}-#{self.updated_at.utc.to_fs(:number)}"
221
221
  else
222
222
  "#{model_cache_key}/#{neo_id}"
223
223
  end
@@ -59,64 +59,4 @@ module ActiveGraph::Shared
59
59
  @identifier_params ||= "#{identifier}_params"
60
60
  end
61
61
  end
62
-
63
- class NodeQueryFactory < QueryFactory
64
- protected
65
-
66
- def match_string
67
- "(#{identifier})"
68
- end
69
-
70
- def create_query
71
- return match_query if graph_object.persisted?
72
- labels = graph_object.labels_for_create.map { |l| ":`#{l}`" }.join
73
- base_query.create("(#{identifier}#{labels} $#{identifier}_params)").params(identifier_params => graph_object.props_for_create)
74
- end
75
- end
76
-
77
- class RelQueryFactory < QueryFactory
78
- protected
79
-
80
- def match_string
81
- "(#{graph_object.from_node_identifier})-[#{identifier}]->()"
82
- end
83
-
84
- def create_query
85
- return match_query if graph_object.persisted?
86
- create_props, set_props = filtered_props
87
- base_query.send(graph_object.create_method, query_string(create_props)).break
88
- .set(identifier => set_props)
89
- .params(params(create_props))
90
- end
91
-
92
- private
93
-
94
- def filtered_props
95
- ActiveGraph::Shared::FilteredHash.new(graph_object.props_for_create, graph_object.creates_unique_option).filtered_base
96
- end
97
-
98
- def query_string(create_props)
99
- "(#{graph_object.from_node_identifier})-[#{identifier}:`#{graph_object.type}` #{pattern(create_props)}]->(#{graph_object.to_node_identifier})"
100
- end
101
-
102
- def params(create_props)
103
- unique? ? create_props.transform_keys { |key| scoped(key).to_sym } : { namespace.to_sym => create_props }
104
- end
105
-
106
- def unique?
107
- graph_object.create_method == :create_unique
108
- end
109
-
110
- def pattern(create_props)
111
- unique? ? "{#{create_props.keys.map { |key| "#{key}: $#{scoped(key)}" }.join(', ')}}" : "$#{namespace}"
112
- end
113
-
114
- def scoped(key)
115
- "#{namespace}_#{key}"
116
- end
117
-
118
- def namespace
119
- "#{identifier}_create_props"
120
- end
121
- end
122
62
  end