neo4j 1.0.0-java → 1.1.0.beta.1-java
Sign up to get free protection for your applications and to get access to all the features.
- data/CONTRIBUTORS +1 -0
- data/Gemfile +1 -0
- data/README.rdoc +1 -0
- data/lib/neo4j/algo/algo.rb +5 -5
- data/lib/neo4j/database.rb +1 -1
- data/lib/neo4j/has_n/class_methods.rb +5 -6
- data/lib/neo4j/has_n/decl_relationship_dsl.rb +32 -21
- data/lib/neo4j/has_n/mapping.rb +4 -5
- data/lib/neo4j/index/indexer.rb +21 -17
- data/lib/neo4j/index/indexer_registry.rb +1 -0
- data/lib/neo4j/index/lucene_query.rb +1 -1
- data/lib/neo4j/jars/core/neo4j-backup-1.3.jar +0 -0
- data/lib/neo4j/jars/core/{neo4j-graph-algo-1.3.M03.jar → neo4j-graph-algo-1.3.jar} +0 -0
- data/lib/neo4j/jars/core/neo4j-kernel-1.3.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-lucene-index-1.3.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-com-1.3.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-ha-1.3.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-jmx-1.3.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-management-1.3.jar +0 -0
- data/lib/neo4j/jars/ha/{neo4j-shell-1.3.M03.jar → neo4j-shell-1.3.jar} +0 -0
- data/lib/neo4j/neo4j.rb +1 -1
- data/lib/neo4j/node.rb +2 -3
- data/lib/neo4j/node_mixin/node_mixin.rb +5 -0
- data/lib/neo4j/property/class_methods.rb +6 -10
- data/lib/neo4j/property/property.rb +0 -2
- data/lib/neo4j/rails/attributes.rb +10 -8
- data/lib/neo4j/rails/callbacks.rb +1 -1
- data/lib/neo4j/rails/finders.rb +1 -1
- data/lib/neo4j/rails/lucene_connection_closer.rb +1 -3
- data/lib/neo4j/rails/mapping/property.rb +112 -35
- data/lib/neo4j/rails/model.rb +10 -0
- data/lib/neo4j/rails/persistence.rb +10 -4
- data/lib/neo4j/rails/rails.rb +6 -2
- data/lib/neo4j/rails/rel_persistence.rb +231 -0
- data/lib/neo4j/rails/relationship.rb +126 -0
- data/lib/neo4j/rails/relationships/node_dsl.rb +91 -0
- data/lib/neo4j/rails/relationships/relationships.rb +47 -40
- data/lib/neo4j/rails/relationships/rels_dsl.rb +82 -0
- data/lib/neo4j/rails/relationships/storage.rb +161 -0
- data/lib/neo4j/rails/serialization.rb +1 -1
- data/lib/neo4j/rails/validations/associated.rb +53 -0
- data/lib/neo4j/rails/validations.rb +2 -3
- data/lib/neo4j/relationship.rb +3 -3
- data/lib/neo4j/relationship_mixin/relationship_mixin.rb +5 -1
- data/lib/neo4j/rels/traverser.rb +12 -12
- data/lib/neo4j/rule/rule_node.rb +2 -1
- data/lib/neo4j/to_java.rb +0 -4
- data/lib/neo4j/traversal/traverser.rb +24 -3
- data/lib/neo4j/type_converters/type_converters.rb +59 -6
- data/lib/neo4j/version.rb +1 -1
- data/lib/neo4j.rb +10 -8
- metadata +21 -16
- data/lib/neo4j/jars/core/neo4j-backup-1.3.M03.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-kernel-1.3.M03.jar +0 -0
- data/lib/neo4j/jars/core/neo4j-lucene-index-1.3.M03.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-com-1.3.M03.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-ha-1.3.M03.jar +0 -0
- data/lib/neo4j/jars/ha/neo4j-management-1.3.M03.jar +0 -0
- data/lib/neo4j/rails/relationships/mapper.rb +0 -103
- data/lib/neo4j/rails/relationships/relationship.rb +0 -30
@@ -1,51 +1,128 @@
|
|
1
1
|
module Neo4j
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
2
|
+
module Rails
|
3
|
+
module Mapping
|
4
|
+
module Property
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
def has_n(*args)
|
10
|
+
options = args.extract_options!
|
11
|
+
define_has_n_methods_for(args.first, options)
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_one(*args)
|
15
|
+
options = args.extract_options!
|
16
|
+
define_has_one_methods_for(args.first, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
def define_has_one_methods_for(rel_type, options)
|
21
|
+
unless method_defined?(rel_type)
|
22
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
23
|
+
def #{rel_type}
|
24
|
+
dsl = _decl_rels_for(:'#{rel_type}')
|
25
|
+
storage = _create_or_get_storage_for_decl_rels(dsl)
|
26
|
+
storage.single_node(dsl.dir)
|
27
|
+
end
|
28
|
+
RUBY
|
29
|
+
end
|
30
|
+
|
31
|
+
unless method_defined?("#{rel_type}_rel")
|
32
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
33
|
+
def #{rel_type}_rel
|
34
|
+
dsl = _decl_rels_for(:'#{rel_type}')
|
35
|
+
storage = _create_or_get_storage_for_decl_rels(dsl)
|
36
|
+
storage.single_relationship(dsl.dir)
|
37
|
+
end
|
38
|
+
RUBY
|
39
|
+
end
|
40
|
+
|
41
|
+
unless method_defined?("#{rel_type}=".to_sym)
|
42
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
43
|
+
def #{rel_type}=(other)
|
44
|
+
dsl = _decl_rels_for(:'#{rel_type}')
|
45
|
+
storage = _create_or_get_storage_for_decl_rels(dsl)
|
46
|
+
rel = storage.single_relationship(dsl.dir)
|
47
|
+
rel && rel.destroy
|
48
|
+
storage.create_relationship_to(other, dsl.dir)
|
49
|
+
end
|
50
|
+
RUBY
|
51
|
+
end
|
52
|
+
_decl_rels[rel_type.to_sym] = Neo4j::HasN::DeclRelationshipDsl.new(rel_type, true, self)
|
53
|
+
end
|
54
|
+
|
55
|
+
def define_has_n_methods_for(rel_type, options)
|
56
|
+
unless method_defined?(rel_type)
|
57
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
58
|
+
def #{rel_type}
|
59
|
+
dsl = _decl_rels_for(:'#{rel_type}')
|
60
|
+
storage = _create_or_get_storage_for_decl_rels(dsl)
|
61
|
+
NodesDSL.new(storage, dsl.dir)
|
62
|
+
end
|
63
|
+
RUBY
|
64
|
+
end
|
65
|
+
|
66
|
+
unless method_defined?("#{rel_type}_rels".to_sym)
|
67
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
68
|
+
def #{rel_type}_rels
|
69
|
+
dsl = _decl_rels_for(:'#{rel_type}')
|
70
|
+
storage = _create_or_get_storage_for_decl_rels(dsl)
|
71
|
+
RelsDSL.new(storage, dsl.dir)
|
72
|
+
end
|
73
|
+
RUBY
|
74
|
+
end
|
75
|
+
|
76
|
+
instance_eval <<-RUBY, __FILE__, __LINE__
|
77
|
+
def #{rel_type}
|
78
|
+
_decl_rels[:'#{rel_type}'].rel_type.to_s
|
79
|
+
end
|
80
|
+
RUBY
|
81
|
+
|
82
|
+
_decl_rels[rel_type.to_sym] = Neo4j::HasN::DeclRelationshipDsl.new(rel_type, false, self)
|
83
|
+
end
|
84
|
+
|
85
|
+
# Handles options for the property
|
86
|
+
#
|
87
|
+
# Set the property type :type => Time
|
88
|
+
# Set a default :default => "default"
|
89
|
+
# Property must be there :null => false
|
90
|
+
# Property has a length limit :limit => 128
|
91
|
+
def property(*args)
|
92
|
+
options = args.extract_options!
|
93
|
+
args.each do |property_sym|
|
94
|
+
property_setup(property_sym, options)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
def property_setup(property, options)
|
100
|
+
_decl_props[property] = options
|
101
|
+
handle_property_options_for(property, options)
|
102
|
+
define_property_methods_for(property, options)
|
103
|
+
end
|
104
|
+
|
105
|
+
def handle_property_options_for(property, options)
|
106
|
+
attribute_defaults[property.to_s] = options[:default] if options.has_key?(:default)
|
107
|
+
|
31
108
|
if options.has_key?(:null) && options[:null] === false
|
32
109
|
validates(property, :non_nil => true, :on => :create)
|
33
110
|
validates(property, :non_nil => true, :on => :update)
|
34
111
|
end
|
35
112
|
validates(property, :length => { :maximum => options[:limit] }) if options[:limit]
|
36
113
|
end
|
37
|
-
|
114
|
+
|
38
115
|
def define_property_methods_for(property, options)
|
39
116
|
unless method_defined?(property)
|
40
117
|
class_eval <<-RUBY, __FILE__, __LINE__
|
41
118
|
def #{property}
|
42
119
|
send(:[], "#{property}")
|
43
120
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
121
|
+
RUBY
|
122
|
+
end
|
123
|
+
|
124
|
+
unless method_defined?("#{property}=".to_sym)
|
125
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
49
126
|
def #{property}=(value)
|
50
127
|
send(:[]=, "#{property}", value)
|
51
128
|
end
|
data/lib/neo4j/rails/model.rb
CHANGED
@@ -3,6 +3,7 @@ module Neo4j
|
|
3
3
|
class Model
|
4
4
|
include Neo4j::NodeMixin
|
5
5
|
|
6
|
+
|
6
7
|
# Initialize a Node with a set of properties (or empty if nothing is passed)
|
7
8
|
def initialize(attributes = {})
|
8
9
|
reset_attributes
|
@@ -14,10 +15,15 @@ module Neo4j
|
|
14
15
|
neo_id.nil? ? nil : neo_id.to_s
|
15
16
|
end
|
16
17
|
|
18
|
+
def hash
|
19
|
+
persisted? ? _java_entity.neo_id.hash : super
|
20
|
+
end
|
21
|
+
|
17
22
|
def to_param
|
18
23
|
persisted? ? neo_id.to_s : nil
|
19
24
|
end
|
20
25
|
|
26
|
+
|
21
27
|
# Returns an Enumerable of all (primary) key attributes
|
22
28
|
# or nil if model.persisted? is false
|
23
29
|
def to_key
|
@@ -57,6 +63,10 @@ module Neo4j
|
|
57
63
|
end
|
58
64
|
end
|
59
65
|
|
66
|
+
def entity_load(id)
|
67
|
+
Neo4j::Node.load(id)
|
68
|
+
end
|
69
|
+
|
60
70
|
##
|
61
71
|
# Determines whether to use Time.local (using :local) or Time.utc (using :utc) when pulling
|
62
72
|
# dates and times from the database. This is set to :local by default.
|
@@ -5,7 +5,7 @@ module Neo4j
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
extend TxMethods
|
8
|
-
tx_methods :destroy, :create, :update, :update_nested_attributes
|
8
|
+
tx_methods :destroy, :create, :update, :update_nested_attributes, :delete
|
9
9
|
end
|
10
10
|
|
11
11
|
# Persist the object to the database. Validations and Callbacks are included
|
@@ -53,7 +53,7 @@ module Neo4j
|
|
53
53
|
|
54
54
|
# Returns true if the object was destroyed.
|
55
55
|
def destroyed?()
|
56
|
-
@_deleted
|
56
|
+
@_deleted || Neo4j::Node._load(id).nil?
|
57
57
|
end
|
58
58
|
|
59
59
|
# Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved.
|
@@ -108,13 +108,19 @@ module Neo4j
|
|
108
108
|
# Initialize a model and set a bunch of attributes at the same time. Returns
|
109
109
|
# the object whether saved successfully or not.
|
110
110
|
def create(*args)
|
111
|
-
new(*args).tap
|
111
|
+
new(*args).tap do |o|
|
112
|
+
yield o if block_given?
|
113
|
+
o.save
|
114
|
+
end
|
112
115
|
end
|
113
116
|
|
114
117
|
# Same as #create, but raises an error if there is a problem during save.
|
115
118
|
# Returns the object whether saved successfully or not.
|
116
119
|
def create!(*args)
|
117
|
-
new(*args).tap
|
120
|
+
new(*args).tap do |o|
|
121
|
+
yield o if block_given?
|
122
|
+
o.save!
|
123
|
+
end
|
118
124
|
end
|
119
125
|
|
120
126
|
# Destroy each node in turn. Runs the destroy callbacks for each node.
|
data/lib/neo4j/rails/rails.rb
CHANGED
@@ -4,6 +4,7 @@ require 'neo4j/rails/transaction'
|
|
4
4
|
require 'neo4j/rails/railtie'
|
5
5
|
require 'neo4j/rails/validations/uniqueness'
|
6
6
|
require 'neo4j/rails/validations/non_nil'
|
7
|
+
require 'neo4j/rails/validations/associated'
|
7
8
|
require 'neo4j/rails/finders'
|
8
9
|
require 'neo4j/rails/mapping/property'
|
9
10
|
require 'neo4j/rails/validations'
|
@@ -12,8 +13,11 @@ require 'neo4j/rails/timestamps'
|
|
12
13
|
require 'neo4j/rails/serialization'
|
13
14
|
require 'neo4j/rails/attributes'
|
14
15
|
require 'neo4j/rails/persistence'
|
15
|
-
require 'neo4j/rails/relationships/
|
16
|
-
require 'neo4j/rails/relationships/
|
16
|
+
require 'neo4j/rails/relationships/storage'
|
17
|
+
require 'neo4j/rails/relationships/node_dsl'
|
18
|
+
require 'neo4j/rails/relationships/rels_dsl'
|
17
19
|
require 'neo4j/rails/relationships/relationships'
|
18
20
|
require 'neo4j/rails/model'
|
19
21
|
require 'neo4j/rails/lucene_connection_closer'
|
22
|
+
require 'neo4j/rails/rel_persistence'
|
23
|
+
require 'neo4j/rails/relationship'
|
@@ -0,0 +1,231 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rails
|
3
|
+
module RelPersistence
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
extend TxMethods
|
8
|
+
tx_methods :destroy, :create, :update, :delete
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
# Persist the object to the database. Validations and Callbacks are included
|
13
|
+
# by default but validation can be disabled by passing :validate => false
|
14
|
+
# to #save.
|
15
|
+
def save(*)
|
16
|
+
create_or_update
|
17
|
+
end
|
18
|
+
|
19
|
+
# Persist the object to the database. Validations and Callbacks are included
|
20
|
+
# by default but validation can be disabled by passing :validate => false
|
21
|
+
# to #save!.
|
22
|
+
#
|
23
|
+
# Raises a RecordInvalidError if there is a problem during save.
|
24
|
+
def save!(*args)
|
25
|
+
unless save(*args)
|
26
|
+
raise RecordInvalidError.new(self)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Updates a single attribute and saves the record.
|
31
|
+
# This is especially useful for boolean flags on existing records. Also note that
|
32
|
+
#
|
33
|
+
# * Validation is skipped.
|
34
|
+
# * Callbacks are invoked.
|
35
|
+
# * Updates all the attributes that are dirty in this object.
|
36
|
+
#
|
37
|
+
def update_attribute(name, value)
|
38
|
+
respond_to?("#{name}=") ? send("#{name}=", value) : self[name] = value
|
39
|
+
save(:validate => false)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Removes the node from Neo4j and freezes the object.
|
43
|
+
def destroy
|
44
|
+
delete
|
45
|
+
freeze
|
46
|
+
end
|
47
|
+
|
48
|
+
# Same as #destroy but doesn't run destroy callbacks and doesn't freeze
|
49
|
+
# the object
|
50
|
+
def delete
|
51
|
+
del unless new_record?
|
52
|
+
set_deleted_properties
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns true if the object was destroyed.
|
56
|
+
def destroyed?()
|
57
|
+
@_deleted || Neo4j::Relationship._load(id).nil?
|
58
|
+
end
|
59
|
+
|
60
|
+
# Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved.
|
61
|
+
# If saving fails because the resource is invalid then false will be returned.
|
62
|
+
def update_attributes(attributes)
|
63
|
+
self.attributes = attributes
|
64
|
+
save
|
65
|
+
end
|
66
|
+
|
67
|
+
# Same as #update_attributes, but raises an exception if saving fails.
|
68
|
+
def update_attributes!(attributes)
|
69
|
+
self.attributes = attributes
|
70
|
+
save!
|
71
|
+
end
|
72
|
+
|
73
|
+
# Reload the object from the DB.
|
74
|
+
def reload(options = nil)
|
75
|
+
clear_changes
|
76
|
+
reset_attributes
|
77
|
+
unless reload_from_database
|
78
|
+
set_deleted_properties
|
79
|
+
freeze
|
80
|
+
end
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
# Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
|
85
|
+
def persisted?
|
86
|
+
!new_record? && !destroyed?
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns true if the record hasn't been saved to Neo4j yet.
|
90
|
+
def new_record?
|
91
|
+
_java_rel.nil?
|
92
|
+
end
|
93
|
+
|
94
|
+
alias :new? :new_record?
|
95
|
+
|
96
|
+
# Freeze the properties hash.
|
97
|
+
def freeze
|
98
|
+
@properties.freeze; self
|
99
|
+
end
|
100
|
+
|
101
|
+
# Returns +true+ if the properties hash has been frozen.
|
102
|
+
def frozen?
|
103
|
+
reload
|
104
|
+
@properties.frozen?
|
105
|
+
end
|
106
|
+
|
107
|
+
module ClassMethods
|
108
|
+
# Initialize a model and set a bunch of attributes at the same time. Returns
|
109
|
+
# the object whether saved successfully or not.
|
110
|
+
def create(*args)
|
111
|
+
new(*args).tap do |o|
|
112
|
+
yield o if block_given?
|
113
|
+
o.save
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Same as #create, but raises an error if there is a problem during save.
|
118
|
+
# Returns the object whether saved successfully or not.
|
119
|
+
def create!(*args)
|
120
|
+
new(*args).tap do |o|
|
121
|
+
yield o if block_given?
|
122
|
+
o.save!
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# Destroy each node in turn. Runs the destroy callbacks for each node.
|
127
|
+
def destroy_all
|
128
|
+
all.each do |n|
|
129
|
+
n.destroy
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
protected
|
135
|
+
def create_or_update
|
136
|
+
result = persisted? ? update : create
|
137
|
+
unless result != false
|
138
|
+
Neo4j::Rails::Transaction.fail if Neo4j::Rails::Transaction.running?
|
139
|
+
false
|
140
|
+
else
|
141
|
+
true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def update
|
146
|
+
write_changed_attributes
|
147
|
+
clear_changes
|
148
|
+
true
|
149
|
+
end
|
150
|
+
|
151
|
+
def create()
|
152
|
+
# prevent calling create twice
|
153
|
+
@start_node.rm_outgoing_rel(type, self)
|
154
|
+
@end_node.rm_incoming_rel(type, self)
|
155
|
+
|
156
|
+
_persist_start_node
|
157
|
+
_persist_end_node
|
158
|
+
|
159
|
+
@_java_rel = Neo4j::Relationship.new(type, start_node, end_node)
|
160
|
+
init_on_create
|
161
|
+
clear_changes
|
162
|
+
true
|
163
|
+
end
|
164
|
+
|
165
|
+
def _load(id)
|
166
|
+
Neo4j::Relationship.load(id)
|
167
|
+
end
|
168
|
+
|
169
|
+
def _persist_start_node
|
170
|
+
unless @start_node.persisted? || @start_node.save
|
171
|
+
# not sure if this can happen - probably a bug
|
172
|
+
raise "Can't save start_node #{@start_node} id #{@start_node.id}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def _persist_end_node
|
177
|
+
unless @end_node.persisted? || @end_node.save
|
178
|
+
raise "Can't save end_node #{@end_node} id #{@end_node.id}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def init_on_create(*)
|
183
|
+
#self["_classname"] = self.class.to_s
|
184
|
+
write_default_attributes
|
185
|
+
write_changed_attributes
|
186
|
+
@_java_rel[:_classname] = self.class.to_s
|
187
|
+
end
|
188
|
+
|
189
|
+
def reset_attributes
|
190
|
+
@properties = {}
|
191
|
+
end
|
192
|
+
|
193
|
+
def reload_from_database
|
194
|
+
if reloaded = self.class.load(id)
|
195
|
+
send(:attributes=, reloaded.attributes, false)
|
196
|
+
end
|
197
|
+
reloaded
|
198
|
+
end
|
199
|
+
|
200
|
+
def set_deleted_properties
|
201
|
+
@_deleted = true
|
202
|
+
@_persisted = false
|
203
|
+
end
|
204
|
+
|
205
|
+
# Ensure any defaults are stored in the DB
|
206
|
+
def write_default_attributes
|
207
|
+
attribute_defaults.each do |attribute, value|
|
208
|
+
write_attribute(attribute, Neo4j::TypeConverters.convert(value, attribute, self.class)) unless changed_attributes.has_key?(attribute) || _java_rel.has_property?(attribute)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Write attributes to the Neo4j DB only if they're altered
|
213
|
+
def write_changed_attributes
|
214
|
+
@properties.each do |attribute, value|
|
215
|
+
write_attribute(attribute, value) if changed_attributes.has_key?(attribute)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
class RecordInvalidError < RuntimeError
|
220
|
+
attr_reader :record
|
221
|
+
|
222
|
+
def initialize(record)
|
223
|
+
@record = record
|
224
|
+
super(@record.errors.full_messages.join(", "))
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
229
|
+
|
230
|
+
end
|
231
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rails
|
3
|
+
class Relationship
|
4
|
+
include Neo4j::RelationshipMixin
|
5
|
+
|
6
|
+
attr_reader :type
|
7
|
+
|
8
|
+
index :_classname
|
9
|
+
|
10
|
+
# Initialize a Node with a set of properties (or empty if nothing is passed)
|
11
|
+
def initialize(*args)
|
12
|
+
@type = args[0]
|
13
|
+
self.start_node = args[1]
|
14
|
+
self.end_node = args[2]
|
15
|
+
attributes = args[3]
|
16
|
+
reset_attributes
|
17
|
+
self.attributes = attributes if attributes.is_a?(Hash)
|
18
|
+
end
|
19
|
+
|
20
|
+
def other_node(node)
|
21
|
+
if persisted?
|
22
|
+
_java_rel.getOtherNode(node._java_node)
|
23
|
+
else
|
24
|
+
@start_node == (node._java_node || node) ? @end_node : @start_node
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
alias_method :get_other_node, :other_node # so it looks like the java version
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
"id: #{self.object_id} start_node: #{start_node.id} end_node: #{end_node.id} type:#{@type}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def id
|
36
|
+
_java_rel.nil? || neo_id.nil? ? nil : neo_id.to_s
|
37
|
+
end
|
38
|
+
|
39
|
+
def hash
|
40
|
+
persisted? ? _java_entity.neo_id.hash : super
|
41
|
+
end
|
42
|
+
|
43
|
+
def start_node
|
44
|
+
@start_node ||= _java_rel && _java_rel.start_node
|
45
|
+
end
|
46
|
+
|
47
|
+
def start_node=(node)
|
48
|
+
old = @start_node
|
49
|
+
@start_node = node
|
50
|
+
# TODO should raise exception if not persisted and changed
|
51
|
+
if old != @start_node
|
52
|
+
old && old.rm_outgoing_rel(type, self)
|
53
|
+
@start_node.class != Neo4j::Node && @start_node.add_outgoing_rel(type, self)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def end_node
|
58
|
+
@end_node ||= _java_rel && _java_rel.end_node
|
59
|
+
end
|
60
|
+
|
61
|
+
def end_node=(node)
|
62
|
+
old = @end_node
|
63
|
+
@end_node = node
|
64
|
+
# TODO should raise exception if not persisted and changed
|
65
|
+
if old != @end_node
|
66
|
+
old && old.rm_incoming_rel(type, self)
|
67
|
+
@end_node.class != Neo4j::Node && @end_node.add_incoming_rel(type, self)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def del
|
72
|
+
_java_rel.del
|
73
|
+
end
|
74
|
+
|
75
|
+
def reset_attributes
|
76
|
+
@properties = {}
|
77
|
+
end
|
78
|
+
|
79
|
+
# --------------------------------------
|
80
|
+
# Public Class Methods
|
81
|
+
# --------------------------------------
|
82
|
+
class << self
|
83
|
+
# NodeMixin overwrites the #new class method but it saves it as orig_new
|
84
|
+
# Here, we just get it back to normal
|
85
|
+
alias :new :orig_new
|
86
|
+
|
87
|
+
def entity_load(id)
|
88
|
+
Neo4j::Relationship.load(id)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def rule(*)
|
93
|
+
end
|
94
|
+
|
95
|
+
def _all
|
96
|
+
_indexer.find(:_classname => self)
|
97
|
+
end
|
98
|
+
|
99
|
+
def load(*ids) # TODO Copied from finders.rb
|
100
|
+
result = ids.map { |id| entity_load(id) }
|
101
|
+
if ids.length == 1
|
102
|
+
result.first
|
103
|
+
else
|
104
|
+
result
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
|
113
|
+
Relationship.class_eval do
|
114
|
+
extend ActiveModel::Translation
|
115
|
+
include RelPersistence # handles how to save, create and update the model
|
116
|
+
include Attributes # handles how to save and retrieve attributes
|
117
|
+
include Mapping::Property # allows some additional options on the #property class method
|
118
|
+
include Serialization # enable to_xml and to_json
|
119
|
+
include Timestamps # handle created_at, updated_at timestamp properties
|
120
|
+
include Validations # enable validations
|
121
|
+
include Callbacks # enable callbacks
|
122
|
+
include Finders # ActiveRecord style find
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|