neo4j 5.0.15 → 5.1.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +60 -5
- data/Gemfile +1 -1
- data/README.md +8 -0
- data/lib/neo4j.rb +4 -0
- data/lib/neo4j/active_node.rb +3 -1
- data/lib/neo4j/active_node/dependent/association_methods.rb +4 -2
- data/lib/neo4j/active_node/dependent/query_proxy_methods.rb +3 -3
- data/lib/neo4j/active_node/has_n.rb +103 -36
- data/lib/neo4j/active_node/has_n/association.rb +10 -33
- data/lib/neo4j/active_node/has_n/association_cypher_methods.rb +108 -0
- data/lib/neo4j/active_node/id_property.rb +19 -11
- data/lib/neo4j/active_node/id_property/accessor.rb +62 -0
- data/lib/neo4j/active_node/labels.rb +13 -2
- data/lib/neo4j/active_node/persistence.rb +19 -4
- data/lib/neo4j/active_node/property.rb +4 -3
- data/lib/neo4j/active_node/query/query_proxy.rb +29 -13
- data/lib/neo4j/active_node/query/query_proxy_eager_loading.rb +8 -0
- data/lib/neo4j/active_node/query/query_proxy_enumerable.rb +7 -0
- data/lib/neo4j/active_node/query/query_proxy_link.rb +16 -6
- data/lib/neo4j/active_node/query/query_proxy_methods.rb +4 -0
- data/lib/neo4j/active_node/query/query_proxy_unpersisted.rb +17 -0
- data/lib/neo4j/active_node/unpersisted.rb +49 -0
- data/lib/neo4j/active_node/validations.rb +1 -1
- data/lib/neo4j/active_rel.rb +17 -0
- data/lib/neo4j/active_rel/persistence.rb +10 -5
- data/lib/neo4j/active_rel/property.rb +17 -5
- data/lib/neo4j/railtie.rb +2 -1
- data/lib/neo4j/shared/declared_property_manager.rb +10 -0
- data/lib/neo4j/shared/initialize.rb +3 -3
- data/lib/neo4j/shared/property.rb +7 -51
- data/lib/neo4j/shared/property/default_property.rb +0 -0
- data/lib/neo4j/shared/type_converters.rb +49 -6
- data/lib/neo4j/shared/typecaster.rb +22 -18
- data/lib/neo4j/shared/validations.rb +1 -1
- data/lib/neo4j/version.rb +1 -1
- data/neo4j.gemspec +1 -1
- metadata +12 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f1d7952f8318fc3525d1e1bfbf90729ddcd02f5
|
4
|
+
data.tar.gz: aaea4557f810905866707c6c19e480b3816efbd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eed94e2d7d99f61592a341e233995b730c312ad8c71bc460f59a8d2b34a4c0cb63b918e803fd2fd13d18f5c221a82d890961fdaac8bf2ed5a122d82252ee044b
|
7
|
+
data.tar.gz: bf2c82d7b1c138964010b6bb80f01b0cc0341babc279adb8ee2a4cd3921d384e064a399927309b5a1114437cb2b86f7e74b2539b742372eec29ec6d55661e5f4
|
data/CHANGELOG.md
CHANGED
@@ -5,30 +5,83 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
5
5
|
|
6
6
|
## [Unreleased][unreleased]
|
7
7
|
|
8
|
-
### Changed
|
9
|
-
- `ActiveNode#destroyed?` and `ActiveRel#destroyed?` now only consider the in-memory state of if an object is destroyed without checking the database
|
10
|
-
|
11
8
|
### Fixed
|
12
9
|
- Added a `before_remove_const` method to clear cached models when Rails `reload!` is called. 5.0.1 included a workaround but this appears to cut to the core of the issue. See https://github.com/neo4jrb/neo4j/pull/855.
|
13
|
-
-
|
10
|
+
- To prevent errors, changing an index to constraint or constraint to index will drop the existing index/constraint before adding the new.
|
11
|
+
- Fixed `AssociationProxy#method_missing` so it properly raises errors.
|
14
12
|
|
15
13
|
### Added
|
16
14
|
- Added ability to view `model_class` from `Association` class for `rails_admin` Neo4j adapter
|
17
15
|
- QueryProxy `where` will now look for declared properties matching hash keys. When found, it will send the value through that property's type converter if the type matches the property's unconverted state.
|
18
16
|
- Improved handling of unpersisted nodes with associations. You can now use `<<` to create associations between unpersisted nodes. A `save` will cascade through unpersisted objects, creating nodes and rels along the way. See https://github.com/neo4jrb/neo4j/pull/871
|
19
17
|
- Support formatted cypher queries for easy reading by humans via the `pretty_logged_cypher_queries` configuration variable
|
18
|
+
- Ability to query for just IDs on associations
|
20
19
|
- On `QueryProxy` objects you can now use an `:id` key in `where` and `find_by` methods to refer to the property from `id_property` (`uuid` by default)
|
20
|
+
- Added `ActiveRel.creates_unique` and deprecated `ActiveRel.creates_unique_rel`
|
21
|
+
- Added #inspect method to ActiveRel to show Cypher-style representation of from node, to node, and relationship type
|
22
|
+
|
23
|
+
### Changed
|
24
|
+
|
25
|
+
- Methods related to ActiveNode's IdProperty module were refactored to improve performance and simplify the API. Existing `default_properties` methods were reworked to reflect their use as-implemented: storage for a single default property, not multiple.
|
26
|
+
- Implementation adjustments that improve node and rel initialization speed, particularly when loading large numbers of objects from the database.
|
27
|
+
|
28
|
+
## [5.0.15] - 08-12-2015
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
|
32
|
+
- `reload!` within Rails apps will work correctly. An earlier release included a workaround but this uses ActiveModel's system for clearing caches to provide a more thorough resolution.
|
33
|
+
|
34
|
+
## [5.0.14] - 08-09-2015
|
35
|
+
|
36
|
+
### Fixed
|
37
|
+
|
38
|
+
- Calling `all` on a QueryProxy chain would cause the currently set node identity within Cypher to be lost.
|
39
|
+
|
40
|
+
## [5.0.13] - 08-07-2015
|
41
|
+
|
42
|
+
### Fixed
|
43
|
+
- Backport AssociationProxy#method_missing fix to raise errors on invalid methods
|
44
|
+
- Fix the count issue on depth two associations (#881)
|
45
|
+
|
46
|
+
## [5.0.12] - ?
|
47
|
+
|
48
|
+
### Fixed
|
49
|
+
- Break between associations so that potential `where` clauses get applied to the correct `(OPTIONAL )MATCH` clause
|
50
|
+
|
51
|
+
### Fixed
|
52
|
+
- Delegate `first` and `last` from `AssociationProxy` to `QueryProxy`
|
53
|
+
- Fix `order` behavior for `first` and `last` in `QueryProxy`
|
54
|
+
|
55
|
+
## [5.0.11] - ?
|
56
|
+
|
57
|
+
### Fixed
|
58
|
+
- Delegate `first` and `last` from `AssociationProxy` to `QueryProxy`
|
59
|
+
- Fix `order` behavior for `first` and `last` in `QueryProxy`
|
60
|
+
|
61
|
+
## [5.0.10] - 2015-07-31
|
62
|
+
|
63
|
+
### Fixed
|
64
|
+
- Fix what should have been a very obvious bug in `_active_record_destroyed_behavior` behavior
|
65
|
+
- Add eager loading to QueryProxy so that it works in all expected places
|
21
66
|
|
22
67
|
## [5.0.9] - 2015-07-29
|
23
|
-
|
68
|
+
|
69
|
+
### Fixed
|
70
|
+
- "NameError: uninitialized constant Class::Date" (https://github.com/neo4jrb/neo4j/issues/852)
|
24
71
|
|
25
72
|
## [5.0.8] - 2015-07-26
|
73
|
+
|
74
|
+
### Changed
|
26
75
|
- Copied QueryClauseMethods doc from master
|
27
76
|
|
28
77
|
## [5.0.7] - 2015-07-26
|
78
|
+
|
79
|
+
### Changed
|
29
80
|
- Copied `docs` folder from master because a lot of work had gone into the docs since 5.0.0 was released
|
30
81
|
|
31
82
|
## [5.0.6] - 2015-07-22
|
83
|
+
|
84
|
+
### Fixed
|
32
85
|
- Fix query logging so that by default it only outputs to the user in the console and development server. Logger can be changed with `neo4j.config.logger` configuration option
|
33
86
|
|
34
87
|
## [5.0.5] - 2015-07-19
|
@@ -45,6 +98,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
45
98
|
|
46
99
|
### Changed
|
47
100
|
- Moved `#with_associations` method from `AssociationProxy` to `QueryProxy` so that all `QueryProxy` chains can benefit from it.
|
101
|
+
- Added `_active_record_destroyed_behavior` semi-hidden configuration variable so that behavior for `ActiveNode#destroyed?` and `ActiveRel#destroyed?` can be changed to upcoming 6.0.0 behavior (matching ActiveRecord) where the database is not accessed.
|
48
102
|
|
49
103
|
## [5.0.2] - 2015-06-30
|
50
104
|
|
@@ -52,6 +106,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
52
106
|
- Fix error when calling `#empty?` or `#blank?` on a query chain with on `order` specified
|
53
107
|
- Make `#find_each` and `#find_in_batches` return the actual objects rather than the result objects
|
54
108
|
- Query logging on console should be to STDOUT with `puts`. Using `Rails.logger` outputs to the file in the `log` directory
|
109
|
+
- Modified queryproxy include? to accept a uuid instead of full node
|
55
110
|
|
56
111
|
## [5.0.1] - 2015-06-23
|
57
112
|
|
data/Gemfile
CHANGED
@@ -2,7 +2,7 @@ source 'http://rubygems.org'
|
|
2
2
|
|
3
3
|
gemspec
|
4
4
|
|
5
|
-
|
5
|
+
gem 'neo4j-core', github: 'neo4jrb/neo4j-core', branch: '5.1.x'
|
6
6
|
# gem 'neo4j-core', path: '../neo4j-core'
|
7
7
|
|
8
8
|
# gem 'active_attr', github: 'neo4jrb/active_attr', branch: 'performance'
|
data/README.md
CHANGED
@@ -12,8 +12,16 @@
|
|
12
12
|
|
13
13
|
## Get Support
|
14
14
|
|
15
|
+
### Documentation
|
16
|
+
|
17
|
+
All new documentation will be done via our [readthedocs](http://neo4jrb.readthedocs.org) site, though some old documentation has yet to be moved from our [wiki](https://github.com/neo4jrb/neo4j/wiki) (also there is the [neo4j-core wiki](https://github.com/neo4jrb/neo4j-core/wiki))
|
18
|
+
|
19
|
+
### Contact Us
|
20
|
+
|
15
21
|
[![StackOverflow](https://img.shields.io/badge/StackOverflow-Ask%20a%20question!-blue.svg)](http://stackoverflow.com/questions/ask?tags=neo4j.rb+neo4j+ruby) [![Gitter](https://img.shields.io/badge/Gitter-Join%20our%20chat!-blue.svg)](https://gitter.im/neo4jrb/neo4j?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Twitter](https://img.shields.io/badge/Twitter-Tweet%20with%20us!-blue.svg)](https://twitter.com/neo4jrb) [![Mailing list](https://img.shields.io/badge/Mailing%20list-Mail%20us!-blue.svg)](https://groups.google.com/forum/#!forum/neo4jrb)
|
16
22
|
|
23
|
+
|
24
|
+
|
17
25
|
# Introduction
|
18
26
|
|
19
27
|
Neo4j.rb is an Active Model compliant Ruby/JRuby wrapper for [the Neo4j graph database](http://www.neo4j.org/). It uses the [neo4j-core](https://github.com/neo4jrb/neo4j-core) and [active_attr](https://github.com/cgriego/active_attr) gems.
|
data/lib/neo4j.rb
CHANGED
@@ -52,12 +52,14 @@ require 'neo4j/active_node/dependent'
|
|
52
52
|
require 'neo4j/active_node/dependent/query_proxy_methods'
|
53
53
|
require 'neo4j/active_node/dependent/association_methods'
|
54
54
|
require 'neo4j/active_node/query_methods'
|
55
|
+
require 'neo4j/active_node/query/query_proxy_unpersisted'
|
55
56
|
require 'neo4j/active_node/query/query_proxy_methods'
|
56
57
|
require 'neo4j/active_node/query/query_proxy_enumerable'
|
57
58
|
require 'neo4j/active_node/query/query_proxy_find_in_batches'
|
58
59
|
require 'neo4j/active_node/query/query_proxy_eager_loading'
|
59
60
|
require 'neo4j/active_node/query/query_proxy_link'
|
60
61
|
require 'neo4j/active_node/labels'
|
62
|
+
require 'neo4j/active_node/id_property/accessor'
|
61
63
|
require 'neo4j/active_node/id_property'
|
62
64
|
require 'neo4j/active_node/callbacks'
|
63
65
|
require 'neo4j/active_node/initialize'
|
@@ -66,7 +68,9 @@ require 'neo4j/active_node/persistence'
|
|
66
68
|
require 'neo4j/active_node/validations'
|
67
69
|
require 'neo4j/active_node/rels'
|
68
70
|
require 'neo4j/active_node/reflection'
|
71
|
+
require 'neo4j/active_node/unpersisted'
|
69
72
|
require 'neo4j/active_node/has_n'
|
73
|
+
require 'neo4j/active_node/has_n/association_cypher_methods'
|
70
74
|
require 'neo4j/active_node/has_n/association'
|
71
75
|
require 'neo4j/active_node/query/query_proxy'
|
72
76
|
require 'neo4j/active_node/query'
|
data/lib/neo4j/active_node.rb
CHANGED
@@ -36,6 +36,7 @@ module Neo4j
|
|
36
36
|
include Neo4j::ActiveNode::Query
|
37
37
|
include Neo4j::ActiveNode::Labels
|
38
38
|
include Neo4j::ActiveNode::Rels
|
39
|
+
include Neo4j::ActiveNode::Unpersisted
|
39
40
|
include Neo4j::ActiveNode::HasN
|
40
41
|
include Neo4j::ActiveNode::Scope
|
41
42
|
include Neo4j::ActiveNode::Dependent
|
@@ -75,7 +76,7 @@ module Neo4j
|
|
75
76
|
|
76
77
|
def self.inherit_id_property(other)
|
77
78
|
Neo4j::Session.on_session_available do |_|
|
78
|
-
|
79
|
+
next if other.manual_id_property? || !self.id_property?
|
79
80
|
id_prop = self.id_property_info
|
80
81
|
conf = id_prop[:type].empty? ? {auto: :uuid} : id_prop[:type]
|
81
82
|
other.id_property id_prop[:name], conf
|
@@ -83,6 +84,7 @@ module Neo4j
|
|
83
84
|
end
|
84
85
|
|
85
86
|
Neo4j::Session.on_session_available do |_|
|
87
|
+
next if manual_id_property?
|
86
88
|
id_property :uuid, auto: :uuid unless self.id_property?
|
87
89
|
|
88
90
|
name = Neo4j::Config[:id_property]
|
@@ -32,11 +32,13 @@ module Neo4j
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def dependent_destroy_callback(object)
|
35
|
-
object.association_query_proxy(name)
|
35
|
+
unique_query = object.association_query_proxy(name)
|
36
|
+
unique_query.each_for_destruction(object, &:destroy) if unique_query
|
36
37
|
end
|
37
38
|
|
38
39
|
def dependent_destroy_orphans_callback(object)
|
39
|
-
object.as(:self).unique_nodes(self, :self, :n, :other_rel)
|
40
|
+
unique_query = object.as(:self).unique_nodes(self, :self, :n, :other_rel)
|
41
|
+
unique_query.each_for_destruction(object, &:destroy) if unique_query
|
40
42
|
end
|
41
43
|
|
42
44
|
# End callback methods
|
@@ -28,7 +28,7 @@ module Neo4j
|
|
28
28
|
# @return [Neo4j::ActiveNode::Query::QueryProxy]
|
29
29
|
def unique_nodes(association, self_identifer, other_node, other_rel)
|
30
30
|
fail 'Only supported by in QueryProxy chains started by an instance' unless source_object
|
31
|
-
|
31
|
+
return false if send(association.name).empty?
|
32
32
|
unique_nodes_query(association, self_identifer, other_node, other_rel)
|
33
33
|
.proxy_as(association.target_class, other_node)
|
34
34
|
end
|
@@ -40,9 +40,9 @@ module Neo4j
|
|
40
40
|
.send(association.name, other_node, other_rel)
|
41
41
|
.query
|
42
42
|
.with(other_node)
|
43
|
-
.match("()#{association.arrow_cypher}(#{other_node})")
|
43
|
+
.match("()#{association.arrow_cypher(:orphan_rel)}(#{other_node})")
|
44
44
|
.with(other_node, count: 'count(*)')
|
45
|
-
.where('count = 1
|
45
|
+
.where('count = {one}', one: 1)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -24,7 +24,7 @@ module Neo4j::ActiveNode
|
|
24
24
|
if @cached_result
|
25
25
|
@cached_result.inspect
|
26
26
|
else
|
27
|
-
"
|
27
|
+
"#<AssociationProxy @query_proxy=#{@query_proxy.inspect}>"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -121,7 +121,7 @@ module Neo4j::ActiveNode
|
|
121
121
|
|
122
122
|
def association_proxy(name, options = {})
|
123
123
|
name = name.to_sym
|
124
|
-
hash = [name, options.values_at(:node, :rel, :labels)].hash
|
124
|
+
hash = [name, options.values_at(:node, :rel, :labels, :rel_length)].hash
|
125
125
|
association_proxy_cache_fetch(hash) do
|
126
126
|
if result_cache = self.instance_variable_get('@source_query_proxy_result_cache')
|
127
127
|
result_by_previous_id = previous_proxy_results_by_previous_id(result_cache, name)
|
@@ -152,27 +152,19 @@ module Neo4j::ActiveNode
|
|
152
152
|
Hash[*query_proxy.pluck('ID(previous)', 'collect(next)').flatten(1)]
|
153
153
|
end
|
154
154
|
|
155
|
-
def handle_non_persisted_node(other_node)
|
156
|
-
return unless Neo4j::Config[:autosave_on_assignment]
|
157
|
-
other_node.try(:save)
|
158
|
-
save
|
159
|
-
end
|
160
|
-
|
161
|
-
def validate_persisted_for_association!
|
162
|
-
fail(Neo4j::ActiveNode::HasN::NonPersistedNodeError, 'Unable to create relationship with non-persisted nodes') unless self._persisted_obj
|
163
|
-
end
|
164
|
-
|
165
155
|
module ClassMethods
|
166
|
-
# :nocov:
|
167
156
|
# rubocop:disable Style/PredicateName
|
157
|
+
|
158
|
+
# :nocov:
|
168
159
|
def has_association?(name)
|
169
160
|
ActiveSupport::Deprecation.warn 'has_association? is deprecated and may be removed from future releases, use association? instead.', caller
|
170
161
|
|
171
162
|
association?(name)
|
172
163
|
end
|
173
|
-
# rubocop:enable Style/PredicateName
|
174
164
|
# :nocov:
|
175
165
|
|
166
|
+
# rubocop:enable Style/PredicateName
|
167
|
+
|
176
168
|
def association?(name)
|
177
169
|
!!associations[name.to_sym]
|
178
170
|
end
|
@@ -195,7 +187,10 @@ module Neo4j::ActiveNode
|
|
195
187
|
# For defining an "has many" association on a model. This defines a set of methods on
|
196
188
|
# your model instances. For instance, if you define the association on a Person model:
|
197
189
|
#
|
198
|
-
#
|
190
|
+
#
|
191
|
+
# .. code-block:: ruby
|
192
|
+
#
|
193
|
+
# has_many :out, :vehicles, type: :has_vehicle
|
199
194
|
#
|
200
195
|
# This would define the following methods:
|
201
196
|
#
|
@@ -213,7 +208,10 @@ module Neo4j::ActiveNode
|
|
213
208
|
# either all ``Person`` nodes (if ``Person.vehicles`` is called), or all ``Vehicle`` objects
|
214
209
|
# associated with the ``Person`` nodes thus far represented in the QueryProxy chain.
|
215
210
|
# For example:
|
216
|
-
#
|
211
|
+
#
|
212
|
+
# .. code-block:: ruby
|
213
|
+
#
|
214
|
+
# company.people.where(age: 40).vehicles
|
217
215
|
#
|
218
216
|
# Arguments:
|
219
217
|
# **direction:**
|
@@ -222,18 +220,24 @@ module Neo4j::ActiveNode
|
|
222
220
|
# Refers to the relative to the model on which the association is being defined.
|
223
221
|
#
|
224
222
|
# Example:
|
225
|
-
# ``Person.has_many :out, :posts, type: :wrote``
|
226
223
|
#
|
227
|
-
#
|
224
|
+
# .. code-block:: ruby
|
225
|
+
#
|
226
|
+
# Person.has_many :out, :posts, type: :wrote
|
227
|
+
#
|
228
|
+
# means that a `WROTE` relationship goes from a `Person` node to a `Post` node
|
228
229
|
#
|
229
230
|
# **name:**
|
230
231
|
# The name of the association. The affects the methods which are created (see above).
|
231
232
|
# The name is also used to form default assumptions about the model which is being referred to
|
232
233
|
#
|
233
234
|
# Example:
|
234
|
-
# ``Person.has_many :out, :posts, type: :wrote``
|
235
235
|
#
|
236
|
-
#
|
236
|
+
# .. code-block:: ruby
|
237
|
+
#
|
238
|
+
# Person.has_many :out, :posts, type: :wrote
|
239
|
+
#
|
240
|
+
# will assume a `model_class` option of ``'Post'`` unless otherwise specified
|
237
241
|
#
|
238
242
|
# **options:** A ``Hash`` of options. Allowed keys are:
|
239
243
|
# *type*: The Neo4j relationship type. This option is required unless either the
|
@@ -243,17 +247,21 @@ module Neo4j::ActiveNode
|
|
243
247
|
# can be gathered.
|
244
248
|
#
|
245
249
|
# Example:
|
246
|
-
# ``Person.has_many :out, :posts, origin: :author`` (`model_class` of `Post` is assumed here)
|
247
250
|
#
|
248
|
-
#
|
251
|
+
# .. code-block:: ruby
|
252
|
+
#
|
253
|
+
# # `model_class` of `Post` is assumed here
|
254
|
+
# Person.has_many :out, :posts, origin: :author
|
255
|
+
#
|
256
|
+
# Post.has_one :in, :author, type: :has_author, model_class: 'Person'
|
249
257
|
#
|
250
258
|
# *model_class*: The model class to which the association is referring. Can be either a
|
251
|
-
# model object ``include`` ing ``ActiveNode`` or a
|
252
|
-
# **A
|
259
|
+
# model object ``include`` ing ``ActiveNode`` or a Symbol/String (or an ``Array`` of same).
|
260
|
+
# **A Symbol or String is recommended** to avoid load-time issues
|
253
261
|
#
|
254
262
|
# *rel_class*: The ``ActiveRel`` class to use for this association. Can be either a
|
255
|
-
# model object ``include`` ing ``ActiveRel`` or a
|
256
|
-
# **A
|
263
|
+
# model object ``include`` ing ``ActiveRel`` or a Symbol/String (or an ``Array`` of same).
|
264
|
+
# **A Symbol or String is recommended** to avoid load-time issues
|
257
265
|
#
|
258
266
|
# *dependent*: Enables deletion cascading.
|
259
267
|
# **Available values:** ``:delete``, ``:delete_orphans``, ``:destroy``, ``:destroy_orphans``
|
@@ -287,13 +295,20 @@ module Neo4j::ActiveNode
|
|
287
295
|
|
288
296
|
def define_has_many_methods(name)
|
289
297
|
define_method(name) do |node = nil, rel = nil, options = {}|
|
290
|
-
return [].freeze unless self._persisted_obj
|
298
|
+
# return [].freeze unless self._persisted_obj
|
299
|
+
|
300
|
+
if node.is_a?(Hash)
|
301
|
+
options = node
|
302
|
+
node = nil
|
303
|
+
end
|
291
304
|
|
292
305
|
association_proxy(name, {node: node, rel: rel, source_object: self, labels: options[:labels]}.merge!(options))
|
293
306
|
end
|
294
307
|
|
295
308
|
define_has_many_setter(name)
|
296
309
|
|
310
|
+
define_has_many_id_methods(name)
|
311
|
+
|
297
312
|
define_class_method(name) do |node = nil, rel = nil, options = {}|
|
298
313
|
association_proxy(name, {node: node, rel: rel, labels: options[:labels]}.merge!(options))
|
299
314
|
end
|
@@ -307,27 +322,79 @@ module Neo4j::ActiveNode
|
|
307
322
|
end
|
308
323
|
end
|
309
324
|
|
310
|
-
def
|
311
|
-
|
312
|
-
|
325
|
+
def define_has_many_id_methods(name)
|
326
|
+
define_method_unless_defined("#{name.to_s.singularize}_ids") do
|
327
|
+
association_proxy(name).pluck(:uuid)
|
328
|
+
end
|
313
329
|
|
314
|
-
|
330
|
+
define_method_unless_defined("#{name.to_s.singularize}_ids=") do |ids|
|
331
|
+
association_proxy(name).replace_with(ids)
|
315
332
|
end
|
316
333
|
|
334
|
+
define_method_unless_defined("#{name.to_s.singularize}_neo_ids") do
|
335
|
+
association_proxy(name).pluck(:neo_id)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def define_method_unless_defined(method_name, &block)
|
340
|
+
define_method(method_name, block) unless respond_to?(method_name)
|
341
|
+
end
|
342
|
+
|
343
|
+
def define_has_one_methods(name)
|
344
|
+
define_has_one_getter(name)
|
345
|
+
|
317
346
|
define_has_one_setter(name)
|
318
347
|
|
348
|
+
define_has_one_id_methods(name)
|
349
|
+
|
319
350
|
define_class_method(name) do |node = nil, rel = nil, options = {}|
|
320
351
|
association_proxy(name, {node: node, rel: rel, labels: options[:labels]}.merge!(options))
|
321
352
|
end
|
322
353
|
end
|
323
354
|
|
355
|
+
def define_has_one_id_methods(name)
|
356
|
+
define_method("#{name}_id") do
|
357
|
+
association_proxy(name).pluck(:uuid).first
|
358
|
+
end
|
359
|
+
|
360
|
+
define_method_unless_defined("#{name}_id=") do |id|
|
361
|
+
association_proxy(name).replace_with(id)
|
362
|
+
end
|
363
|
+
|
364
|
+
define_method("#{name}_neo_id") do
|
365
|
+
association_proxy(name).pluck(:neo_id).first
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def define_has_one_getter(name)
|
370
|
+
define_method(name) do |node = nil, rel = nil, options = {}|
|
371
|
+
return nil unless self._persisted_obj
|
372
|
+
|
373
|
+
if node.is_a?(Hash)
|
374
|
+
options = node
|
375
|
+
node = nil
|
376
|
+
end
|
377
|
+
|
378
|
+
# Return all results if a variable-length relationship length was given
|
379
|
+
results = association_proxy(name, {node: node, rel: rel}.merge!(options))
|
380
|
+
if options[:rel_length] && !options[:rel_length].is_a?(Fixnum)
|
381
|
+
results
|
382
|
+
else
|
383
|
+
results.first
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
324
388
|
def define_has_one_setter(name)
|
325
389
|
define_method("#{name}=") do |other_node|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
390
|
+
if persisted?
|
391
|
+
other_node.save if other_node.respond_to?(:persisted?) && !other_node.persisted?
|
392
|
+
association_proxy_cache.clear # TODO: Should probably just clear for this association...
|
393
|
+
Neo4j::Transaction.run { association_proxy(name).replace_with(other_node) }
|
394
|
+
# handle_non_persisted_node(other_node)
|
395
|
+
else
|
396
|
+
association_proxy(name).defer_create(other_node, {}, :'=')
|
397
|
+
end
|
331
398
|
end
|
332
399
|
end
|
333
400
|
|