neo4j 1.0.0.beta.21-java
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.
- data/CHANGELOG +141 -0
- data/CONTRIBUTORS +17 -0
- data/Gemfile +16 -0
- data/README.rdoc +135 -0
- data/lib/generators/neo4j.rb +65 -0
- data/lib/generators/neo4j/model/model_generator.rb +39 -0
- data/lib/generators/neo4j/model/templates/model.erb +7 -0
- data/lib/neo4j.rb +77 -0
- data/lib/neo4j/config.rb +153 -0
- data/lib/neo4j/database.rb +56 -0
- data/lib/neo4j/equal.rb +21 -0
- data/lib/neo4j/event_handler.rb +116 -0
- data/lib/neo4j/index/class_methods.rb +62 -0
- data/lib/neo4j/index/index.rb +33 -0
- data/lib/neo4j/index/indexer.rb +312 -0
- data/lib/neo4j/index/indexer_registry.rb +68 -0
- data/lib/neo4j/index/lucene_query.rb +191 -0
- data/lib/neo4j/jars/geronimo-jta_1.1_spec-1.1.1.jar +0 -0
- data/lib/neo4j/jars/lucene-core-3.0.2.jar +0 -0
- data/lib/neo4j/jars/neo4j-index-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-kernel-1.2-1.2.M03.jar +0 -0
- data/lib/neo4j/jars/neo4j-lucene-index-0.2-1.2.M03.jar +0 -0
- data/lib/neo4j/load.rb +21 -0
- data/lib/neo4j/mapping/class_methods/init_node.rb +50 -0
- data/lib/neo4j/mapping/class_methods/init_rel.rb +35 -0
- data/lib/neo4j/mapping/class_methods/list.rb +13 -0
- data/lib/neo4j/mapping/class_methods/property.rb +82 -0
- data/lib/neo4j/mapping/class_methods/relationship.rb +91 -0
- data/lib/neo4j/mapping/class_methods/rule.rb +295 -0
- data/lib/neo4j/mapping/decl_relationship_dsl.rb +214 -0
- data/lib/neo4j/mapping/has_list.rb +134 -0
- data/lib/neo4j/mapping/has_n.rb +83 -0
- data/lib/neo4j/mapping/node_mixin.rb +112 -0
- data/lib/neo4j/mapping/relationship_mixin.rb +120 -0
- data/lib/neo4j/model.rb +4 -0
- data/lib/neo4j/neo4j.rb +95 -0
- data/lib/neo4j/node.rb +131 -0
- data/lib/neo4j/node_mixin.rb +4 -0
- data/lib/neo4j/node_relationship.rb +149 -0
- data/lib/neo4j/node_traverser.rb +157 -0
- data/lib/neo4j/property.rb +111 -0
- data/lib/neo4j/rails/attributes.rb +155 -0
- data/lib/neo4j/rails/callbacks.rb +34 -0
- data/lib/neo4j/rails/finders.rb +134 -0
- data/lib/neo4j/rails/lucene_connection_closer.rb +19 -0
- data/lib/neo4j/rails/mapping/property.rb +60 -0
- data/lib/neo4j/rails/model.rb +105 -0
- data/lib/neo4j/rails/persistence.rb +260 -0
- data/lib/neo4j/rails/railtie.rb +21 -0
- data/lib/neo4j/rails/relationships/mapper.rb +96 -0
- data/lib/neo4j/rails/relationships/relationship.rb +30 -0
- data/lib/neo4j/rails/relationships/relationships.rb +60 -0
- data/lib/neo4j/rails/serialization.rb +25 -0
- data/lib/neo4j/rails/timestamps.rb +65 -0
- data/lib/neo4j/rails/transaction.rb +67 -0
- data/lib/neo4j/rails/tx_methods.rb +15 -0
- data/lib/neo4j/rails/validations.rb +38 -0
- data/lib/neo4j/rails/validations/non_nil.rb +11 -0
- data/lib/neo4j/rails/validations/uniqueness.rb +37 -0
- data/lib/neo4j/relationship.rb +169 -0
- data/lib/neo4j/relationship_mixin.rb +4 -0
- data/lib/neo4j/relationship_traverser.rb +92 -0
- data/lib/neo4j/to_java.rb +31 -0
- data/lib/neo4j/transaction.rb +68 -0
- data/lib/neo4j/type_converters.rb +117 -0
- data/lib/neo4j/version.rb +3 -0
- data/lib/orm_adapter/adapters/neo4j.rb +55 -0
- data/lib/tmp/neo4j/active_tx_log +1 -0
- data/lib/tmp/neo4j/index/lucene-store.db +0 -0
- data/lib/tmp/neo4j/index/lucene.log.active +0 -0
- data/lib/tmp/neo4j/lucene-fulltext/lucene-store.db +0 -0
- data/lib/tmp/neo4j/lucene-fulltext/lucene.log.active +0 -0
- data/lib/tmp/neo4j/lucene/lucene-store.db +0 -0
- data/lib/tmp/neo4j/lucene/lucene.log.active +0 -0
- data/lib/tmp/neo4j/messages.log +85 -0
- data/lib/tmp/neo4j/neostore +0 -0
- data/lib/tmp/neo4j/neostore.id +0 -0
- data/lib/tmp/neo4j/neostore.nodestore.db +0 -0
- data/lib/tmp/neo4j/neostore.nodestore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.arrays +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.arrays.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index.keys +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.index.keys.id +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.strings +0 -0
- data/lib/tmp/neo4j/neostore.propertystore.db.strings.id +0 -0
- data/lib/tmp/neo4j/neostore.relationshipstore.db +0 -0
- data/lib/tmp/neo4j/neostore.relationshipstore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db.id +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names +0 -0
- data/lib/tmp/neo4j/neostore.relationshiptypestore.db.names.id +0 -0
- data/lib/tmp/neo4j/nioneo_logical.log.active +0 -0
- data/lib/tmp/neo4j/tm_tx_log.1 +0 -0
- data/neo4j.gemspec +31 -0
- metadata +216 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
module Neo4j
|
2
|
+
|
3
|
+
class PruneEvaluator # :nodoc:
|
4
|
+
include org.neo4j.graphdb.traversal.PruneEvaluator
|
5
|
+
def initialize(proc)
|
6
|
+
@proc = proc
|
7
|
+
end
|
8
|
+
|
9
|
+
def prune_after(path)
|
10
|
+
@proc.call(path)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class FilterPredicate # :nodoc:
|
15
|
+
include org.neo4j.helpers.Predicate
|
16
|
+
def initialize
|
17
|
+
@procs = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def add(proc)
|
21
|
+
@procs << proc
|
22
|
+
end
|
23
|
+
|
24
|
+
def include_start_node
|
25
|
+
@include_start_node = true
|
26
|
+
end
|
27
|
+
|
28
|
+
def accept(path)
|
29
|
+
return false if @include_start_node && path.length == 0
|
30
|
+
# find the first filter which returns false
|
31
|
+
# if not found then we will accept this path
|
32
|
+
@procs.find {|p| !p.call(path)}.nil?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
class NodeTraverser
|
38
|
+
include Enumerable
|
39
|
+
include ToJava
|
40
|
+
|
41
|
+
def initialize(from, type = nil, dir=nil)
|
42
|
+
@from = from
|
43
|
+
@depth = 1
|
44
|
+
if type.nil? || dir.nil?
|
45
|
+
@td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first()
|
46
|
+
else
|
47
|
+
@type = type_to_java(type)
|
48
|
+
@dir = dir_to_java(dir)
|
49
|
+
@td = org.neo4j.kernel.impl.traversal.TraversalDescriptionImpl.new.breadth_first().relationships(@type, @dir)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
"NodeTraverser [from: #{@from.neo_id} depth: #{@depth} type: #{@type} dir:#{@dir}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def <<(other_node)
|
59
|
+
new(other_node)
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
def new(other_node)
|
64
|
+
case @dir
|
65
|
+
when org.neo4j.graphdb.Direction::OUTGOING
|
66
|
+
@from.create_relationship_to(other_node, @type)
|
67
|
+
when org.neo4j.graphdb.Direction::INCOMING
|
68
|
+
other_node._java_node.create_relationship_to(@from, @type)
|
69
|
+
else
|
70
|
+
raise "Only allowed to create outgoing or incoming relationships (not #@dir)"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def both(type)
|
75
|
+
@type = type_to_java(type) if type
|
76
|
+
@dir = dir_to_java(:both)
|
77
|
+
@td = @td.relationships(type_to_java(type), @dir)
|
78
|
+
self
|
79
|
+
end
|
80
|
+
|
81
|
+
def outgoing(type)
|
82
|
+
@type = type_to_java(type) if type
|
83
|
+
@dir = dir_to_java(:outgoing)
|
84
|
+
@td = @td.relationships(type_to_java(type), @dir)
|
85
|
+
self
|
86
|
+
end
|
87
|
+
|
88
|
+
def incoming(type)
|
89
|
+
@type = type_to_java(type) if type
|
90
|
+
@dir = dir_to_java(:incoming)
|
91
|
+
@td = @td.relationships(type_to_java(type), @dir)
|
92
|
+
self
|
93
|
+
end
|
94
|
+
|
95
|
+
def filter_method(name, &proc)
|
96
|
+
# add method name
|
97
|
+
singelton = class << self; self; end
|
98
|
+
singelton.send(:define_method, name) {filter &proc}
|
99
|
+
self
|
100
|
+
end
|
101
|
+
|
102
|
+
def prune(&block)
|
103
|
+
@td = @td.prune(PruneEvaluator.new(block))
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
107
|
+
def filter(&block)
|
108
|
+
# we keep a reference to filter predicate since only one filter is allowed and we might want to modify it
|
109
|
+
@filter_predicate ||= FilterPredicate.new
|
110
|
+
@filter_predicate.add(block)
|
111
|
+
@td = @td.filter(@filter_predicate)
|
112
|
+
self
|
113
|
+
end
|
114
|
+
|
115
|
+
# Sets depth, if :all then it will traverse any depth
|
116
|
+
def depth(d)
|
117
|
+
@depth = d
|
118
|
+
self
|
119
|
+
end
|
120
|
+
|
121
|
+
def include_start_node
|
122
|
+
@include_start_node = true
|
123
|
+
self
|
124
|
+
end
|
125
|
+
|
126
|
+
def size
|
127
|
+
[*self].size
|
128
|
+
end
|
129
|
+
|
130
|
+
alias_method :length, :size
|
131
|
+
|
132
|
+
def [](index)
|
133
|
+
each_with_index {|node,i| break node if index == i}
|
134
|
+
end
|
135
|
+
|
136
|
+
def empty?
|
137
|
+
first == nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def each
|
141
|
+
iterator.each {|i| yield i.wrapper}
|
142
|
+
end
|
143
|
+
|
144
|
+
def iterator
|
145
|
+
unless @include_start_node
|
146
|
+
if @filter_predicate
|
147
|
+
@filter_predicate.include_start_node
|
148
|
+
else
|
149
|
+
@td = @td.filter(org.neo4j.kernel.Traversal.return_all_but_start_node)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
@td = @td.prune(org.neo4j.kernel.Traversal.pruneAfterDepth( @depth ) ) unless @depth == :all
|
153
|
+
@td.traverse(@from).nodes
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Property
|
3
|
+
|
4
|
+
# Returns a hash of all properties
|
5
|
+
# It also include the id of the node with the key <tt>_neo_id</tt>
|
6
|
+
#
|
7
|
+
def props
|
8
|
+
ret = {"_neo_id" => neo_id}
|
9
|
+
iter = getPropertyKeys.iterator
|
10
|
+
while (iter.hasNext) do
|
11
|
+
key = iter.next
|
12
|
+
ret[key] = get_property(key)
|
13
|
+
end
|
14
|
+
ret
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns the unique id of this node.
|
18
|
+
# Ids are garbage collected over time so they are only guaranteed to be unique during a specific time span:
|
19
|
+
# if the node is deleted, it's likely that a new node at some point will get the old id. Note:
|
20
|
+
# this makes node ids brittle as public APIs.
|
21
|
+
def neo_id
|
22
|
+
getId
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a hash of properties with keys not starting with <tt>_</tt>
|
26
|
+
# That means that the neo_id will not be included in the returned hash.
|
27
|
+
#
|
28
|
+
def attributes
|
29
|
+
attr = props
|
30
|
+
ret = {}
|
31
|
+
attr.each_pair { |k, v| ret[k] = wrapper.respond_to?(k) ? wrapper.send(k) : v unless k.to_s[0] == ?_ }
|
32
|
+
ret
|
33
|
+
end
|
34
|
+
|
35
|
+
# Checks if the given key exist as a property.
|
36
|
+
def property?(key)
|
37
|
+
has_property?(key.to_s)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Updates this node/relationship's properties by using the provided struct/hash.
|
41
|
+
# If the option <code>{:strict => true}</code> is given, any properties present on
|
42
|
+
# the node but not present in the hash will be removed from the node.
|
43
|
+
#
|
44
|
+
# ==== Parameters
|
45
|
+
# struct_or_hash:: the key and value to be set, should respond to <tt>each_pair</tt>
|
46
|
+
# options:: further options defining the context of the update, should be a Hash
|
47
|
+
#
|
48
|
+
# ==== Returns
|
49
|
+
# self
|
50
|
+
#
|
51
|
+
def update(struct_or_hash, options={})
|
52
|
+
strict = options[:strict]
|
53
|
+
keys_to_delete = props.keys - %w(_neo_id _classname) if strict
|
54
|
+
struct_or_hash.each_pair do |key, value|
|
55
|
+
next if %w(_neo_id _classname).include? key.to_s
|
56
|
+
# do not allow special properties to be mass assigned
|
57
|
+
keys_to_delete.delete(key) if strict
|
58
|
+
setter_meth = "#{key}=".to_sym
|
59
|
+
if @_wrapper && @_wrapper.respond_to?(setter_meth)
|
60
|
+
@_wrapper.send(setter_meth, value)
|
61
|
+
else
|
62
|
+
self[key] = value
|
63
|
+
end
|
64
|
+
end
|
65
|
+
keys_to_delete.each { |key| delete_property(key) } if strict
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# Returns the value of the given key or nil if the property does not exist.
|
71
|
+
def [](key)
|
72
|
+
return unless property?(key)
|
73
|
+
val = get_property(key.to_s)
|
74
|
+
val.class.superclass == ArrayJavaProxy ? val.to_a : val
|
75
|
+
end
|
76
|
+
|
77
|
+
# Sets the property of this node.
|
78
|
+
# Property keys are always strings. Valid property value types are the primitives(<tt>String</tt>, <tt>Fixnum</tt>, <tt>Float</tt>, <tt>FalseClass</tt>, <tt>TrueClass</tt>) or array of those primitives.
|
79
|
+
#
|
80
|
+
# ==== Gotchas
|
81
|
+
# * Values in the array must be of the same type.
|
82
|
+
# * You can *not* delete or add one item in the array (e.g. person.phones.delete('123')) but instead you must create a new array instead.
|
83
|
+
#
|
84
|
+
def []=(key, value)
|
85
|
+
k = key.to_s
|
86
|
+
if value.nil?
|
87
|
+
remove_property(k)
|
88
|
+
elsif (Array === value)
|
89
|
+
case value[0]
|
90
|
+
when NilClass
|
91
|
+
set_property(k, [].to_java(:string))
|
92
|
+
when String
|
93
|
+
set_property(k, value.to_java(:string))
|
94
|
+
when Float
|
95
|
+
set_property(k, value.to_java(:double))
|
96
|
+
when FalseClass, TrueClass
|
97
|
+
set_property(k, value.to_java(:boolean))
|
98
|
+
when Fixnum
|
99
|
+
set_property(k, value.to_java(:long))
|
100
|
+
when Boolean
|
101
|
+
set_property(k, value.to_java(:boolean))
|
102
|
+
else
|
103
|
+
raise "Not allowed to store array with value #{value[0]} type #{value[0].class}"
|
104
|
+
end
|
105
|
+
else
|
106
|
+
set_property(k, value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
# This module handles the getting, setting and updating of attributes or properties
|
2
|
+
# in a Railsy way. This typically means not writing anything to the DB until the
|
3
|
+
# object is saved (after validation).
|
4
|
+
#
|
5
|
+
# Externally, when we talk about properties (e.g. #property?, #property_names, #properties),
|
6
|
+
# we mean all of the stored properties for this object include the 'hidden' props
|
7
|
+
# with underscores at the beginning such as _neo_id and _classname. When we talk
|
8
|
+
# about attributes, we mean all the properties apart from those hidden ones.
|
9
|
+
module Neo4j
|
10
|
+
module Rails
|
11
|
+
module Attributes
|
12
|
+
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
included do
|
15
|
+
include ActiveModel::Dirty # track changes to attributes
|
16
|
+
include ActiveModel::MassAssignmentSecurity # handle attribute hash assignment
|
17
|
+
|
18
|
+
class_inheritable_hash :attribute_defaults
|
19
|
+
self.attribute_defaults ||= {}
|
20
|
+
|
21
|
+
# save the original [] and []= to use as read/write to Neo4j
|
22
|
+
alias_method :read_attribute, :[]
|
23
|
+
alias_method :write_attribute, :[]=
|
24
|
+
|
25
|
+
# wrap the read/write in type conversion
|
26
|
+
alias_method_chain :read_local_property, :type_conversion
|
27
|
+
alias_method_chain :write_local_property, :type_conversion
|
28
|
+
|
29
|
+
# whenever we refer to [] or []=. use our local properties store
|
30
|
+
alias_method :[], :read_local_property
|
31
|
+
alias_method :[]=, :write_local_property
|
32
|
+
end
|
33
|
+
|
34
|
+
# The behaviour of []= changes with a Rails Model, where nothing gets written
|
35
|
+
# to Neo4j until the object is saved, during which time all the validations
|
36
|
+
# and callbacks are run to ensure correctness
|
37
|
+
def write_local_property(key, value)
|
38
|
+
key_s = key.to_s
|
39
|
+
if @properties[key_s] != value
|
40
|
+
attribute_will_change!(key_s)
|
41
|
+
@properties[key_s] = value
|
42
|
+
end
|
43
|
+
value
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns the locally stored value for the key or retrieves the value from
|
47
|
+
# the DB if we don't have one
|
48
|
+
def read_local_property(key)
|
49
|
+
key = key.to_s
|
50
|
+
if @properties.has_key?(key)
|
51
|
+
@properties[key]
|
52
|
+
else
|
53
|
+
@properties[key] = (persisted? && _java_node.has_property?(key)) ? read_attribute(key) : attribute_defaults[key]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Mass-assign attributes. Stops any protected attributes from being assigned.
|
58
|
+
def attributes=(attributes, guard_protected_attributes = true)
|
59
|
+
attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes
|
60
|
+
attributes.each { |k, v| respond_to?("#{k}=") ? send("#{k}=", v) : self[k] = v }
|
61
|
+
end
|
62
|
+
|
63
|
+
# Tracks the current changes and clears the changed attributes hash. Called
|
64
|
+
# after saving the object.
|
65
|
+
def clear_changes
|
66
|
+
@previously_changed = changes
|
67
|
+
@changed_attributes.clear
|
68
|
+
end
|
69
|
+
|
70
|
+
# Return the properties from the Neo4j Node, merged with those that haven't
|
71
|
+
# yet been saved
|
72
|
+
def props
|
73
|
+
ret = {}
|
74
|
+
property_names.each do |property_name|
|
75
|
+
ret[property_name] = respond_to?(property_name) ? send(property_name) : send(:[], property_name)
|
76
|
+
end
|
77
|
+
ret
|
78
|
+
end
|
79
|
+
|
80
|
+
# Return all the attributes for this model as a hash attr => value. Doesn't
|
81
|
+
# include properties that start with <tt>_</tt>.
|
82
|
+
def attributes
|
83
|
+
ret = {}
|
84
|
+
attribute_names.each do |attribute_name|
|
85
|
+
ret[attribute_name] = respond_to?(attribute_name) ? send(attribute_name) : send(:[], attribute_name)
|
86
|
+
end
|
87
|
+
ret
|
88
|
+
end
|
89
|
+
|
90
|
+
# Known properties are either in the @properties, the declared
|
91
|
+
# attributes or the property keys for the persisted node.
|
92
|
+
def property_names
|
93
|
+
keys = @properties.keys + self.class._decl_props.keys.map { |k| k.to_s }
|
94
|
+
keys += _java_node.property_keys.to_a if persisted?
|
95
|
+
keys.flatten.uniq
|
96
|
+
end
|
97
|
+
|
98
|
+
# Known attributes are either in the @properties, the declared
|
99
|
+
# attributes or the property keys for the persisted node. Any attributes
|
100
|
+
# that start with <tt>_</tt> are rejected
|
101
|
+
def attribute_names
|
102
|
+
property_names.reject { |property_name| property_name[0] == ?_ }
|
103
|
+
end
|
104
|
+
|
105
|
+
# Known properties are either in the @properties, the declared
|
106
|
+
# properties or the property keys for the persisted node
|
107
|
+
def property?(name)
|
108
|
+
@properties.keys.include?(name) ||
|
109
|
+
self.class._decl_props.map { |k| k.to_s }.include?(name) ||
|
110
|
+
begin
|
111
|
+
super
|
112
|
+
rescue org.neo4j.graphdb.NotFoundException
|
113
|
+
set_deleted_properties
|
114
|
+
nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
# Return true if method_name is the name of an appropriate attribute
|
119
|
+
# method
|
120
|
+
def attribute?(name)
|
121
|
+
name[0] != ?_ && property?(name)
|
122
|
+
end
|
123
|
+
|
124
|
+
# To get ActiveModel::Dirty to work, we need to be able to call undeclared
|
125
|
+
# properties as though they have get methods
|
126
|
+
def method_missing(method_id, *args, &block)
|
127
|
+
method_name = method_id.to_s
|
128
|
+
if property?(method_name)
|
129
|
+
self[method_name]
|
130
|
+
else
|
131
|
+
super
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def respond_to?(method_id, include_private = false)
|
136
|
+
method_name = method_id.to_s
|
137
|
+
if property?(method_name)
|
138
|
+
true
|
139
|
+
else
|
140
|
+
super
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Wrap the getter in a conversion from Java to Ruby
|
145
|
+
def read_local_property_with_type_conversion(property)
|
146
|
+
Neo4j::TypeConverters.to_ruby(self.class, property, read_local_property_without_type_conversion(property))
|
147
|
+
end
|
148
|
+
|
149
|
+
# Wrap the setter in a conversion from Ruby to Java
|
150
|
+
def write_local_property_with_type_conversion(property, value)
|
151
|
+
write_local_property_without_type_conversion(property, Neo4j::TypeConverters.to_java(self.class, property, value))
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Rails
|
3
|
+
module Callbacks
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
[:create_or_update, :create, :update, :destroy].each do |method|
|
8
|
+
alias_method_chain method, :callbacks
|
9
|
+
end
|
10
|
+
|
11
|
+
extend ActiveModel::Callbacks
|
12
|
+
|
13
|
+
define_model_callbacks :create, :save, :update, :destroy
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy_with_callbacks #:nodoc:
|
17
|
+
_run_destroy_callbacks { destroy_without_callbacks }
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def create_or_update_with_callbacks #:nodoc:
|
22
|
+
_run_save_callbacks { create_or_update_without_callbacks }
|
23
|
+
end
|
24
|
+
|
25
|
+
def create_with_callbacks #:nodoc:
|
26
|
+
_run_create_callbacks { create_without_callbacks }
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_with_callbacks(*) #:nodoc:
|
30
|
+
_run_update_callbacks { update_without_callbacks }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|