neo4j 4.1.5 → 5.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +584 -0
  3. data/CONTRIBUTORS +7 -28
  4. data/Gemfile +6 -1
  5. data/README.md +54 -8
  6. data/lib/neo4j.rb +5 -0
  7. data/lib/neo4j/active_node.rb +1 -0
  8. data/lib/neo4j/active_node/dependent/association_methods.rb +35 -17
  9. data/lib/neo4j/active_node/dependent/query_proxy_methods.rb +21 -19
  10. data/lib/neo4j/active_node/has_n.rb +377 -132
  11. data/lib/neo4j/active_node/has_n/association.rb +77 -38
  12. data/lib/neo4j/active_node/id_property.rb +46 -28
  13. data/lib/neo4j/active_node/initialize.rb +18 -6
  14. data/lib/neo4j/active_node/labels.rb +69 -35
  15. data/lib/neo4j/active_node/node_wrapper.rb +37 -30
  16. data/lib/neo4j/active_node/orm_adapter.rb +5 -4
  17. data/lib/neo4j/active_node/persistence.rb +53 -10
  18. data/lib/neo4j/active_node/property.rb +13 -5
  19. data/lib/neo4j/active_node/query.rb +11 -10
  20. data/lib/neo4j/active_node/query/query_proxy.rb +126 -153
  21. data/lib/neo4j/active_node/query/query_proxy_enumerable.rb +15 -25
  22. data/lib/neo4j/active_node/query/query_proxy_link.rb +89 -0
  23. data/lib/neo4j/active_node/query/query_proxy_methods.rb +72 -19
  24. data/lib/neo4j/active_node/query_methods.rb +3 -1
  25. data/lib/neo4j/active_node/scope.rb +17 -21
  26. data/lib/neo4j/active_node/validations.rb +8 -2
  27. data/lib/neo4j/active_rel/initialize.rb +1 -2
  28. data/lib/neo4j/active_rel/persistence.rb +21 -33
  29. data/lib/neo4j/active_rel/property.rb +4 -2
  30. data/lib/neo4j/active_rel/types.rb +20 -8
  31. data/lib/neo4j/config.rb +16 -6
  32. data/lib/neo4j/core/query.rb +2 -2
  33. data/lib/neo4j/errors.rb +10 -0
  34. data/lib/neo4j/migration.rb +57 -46
  35. data/lib/neo4j/paginated.rb +3 -1
  36. data/lib/neo4j/railtie.rb +26 -14
  37. data/lib/neo4j/shared.rb +7 -1
  38. data/lib/neo4j/shared/declared_property.rb +62 -0
  39. data/lib/neo4j/shared/declared_property_manager.rb +150 -0
  40. data/lib/neo4j/shared/persistence.rb +15 -8
  41. data/lib/neo4j/shared/property.rb +64 -49
  42. data/lib/neo4j/shared/rel_type_converters.rb +13 -12
  43. data/lib/neo4j/shared/serialized_properties.rb +0 -15
  44. data/lib/neo4j/shared/type_converters.rb +53 -47
  45. data/lib/neo4j/shared/typecaster.rb +49 -0
  46. data/lib/neo4j/version.rb +1 -1
  47. data/lib/rails/generators/neo4j/model/model_generator.rb +3 -3
  48. data/lib/rails/generators/neo4j_generator.rb +5 -12
  49. data/neo4j.gemspec +4 -3
  50. metadata +30 -11
  51. data/CHANGELOG +0 -545
@@ -17,42 +17,51 @@ module Neo4j
17
17
  apply_vars_from_options(options)
18
18
  end
19
19
 
20
- def target_class_option(options)
21
- if options[:model_class].nil?
20
+ def target_class_option(model_class)
21
+ case model_class
22
+ when nil
22
23
  if @target_class_name_from_name
23
- "::#{@target_class_name_from_name}"
24
+ "#{association_model_namespace}::#{@target_class_name_from_name}"
24
25
  else
25
26
  @target_class_name_from_name
26
27
  end
27
- elsif options[:model_class] == false
28
+ when Array
29
+ model_class.map { |sub_model_class| target_class_option(sub_model_class) }
30
+ when false
28
31
  false
29
32
  else
30
- "::#{options[:model_class]}"
33
+ "::#{model_class}"
31
34
  end
32
35
  end
33
36
 
34
37
  # Return cypher partial query string for the relationship part of a MATCH (arrow / relationship definition)
35
- def arrow_cypher(var = nil, properties = {}, create = false)
38
+ def arrow_cypher(var = nil, properties = {}, create = false, reverse = false)
36
39
  validate_origin!
37
- relationship_type = relationship_type(create)
38
- relationship_name_cypher = ":`#{relationship_type}`" if relationship_type
39
- properties_string = get_properties_string(properties)
40
- relationship_cypher = get_relationship_cypher(var, relationship_name_cypher, properties_string)
41
- get_direction(relationship_cypher, create)
40
+ direction_cypher(get_relationship_cypher(var, properties, create), create, reverse)
42
41
  end
43
42
 
44
- def target_class_name
45
- @target_class_name ||= @target_class_option.to_s if @target_class_option
43
+ def target_class_names
44
+ @target_class_names ||= if @target_class_option.is_a?(Array)
45
+ @target_class_option.map(&:to_s)
46
+ elsif @target_class_option
47
+ [@target_class_option.to_s]
48
+ end
46
49
  end
47
50
 
48
- def target_class_name_or_nil
49
- @target_class_name_or_nil ||= target_class_name || 'nil'
51
+ def target_classes_or_nil
52
+ @target_classes_or_nil ||= discovered_model if target_class_names
53
+ end
54
+
55
+ def discovered_model
56
+ target_class_names.map(&:constantize).select do |constant|
57
+ constant.ancestors.include?(::Neo4j::ActiveNode)
58
+ end
50
59
  end
51
60
 
52
61
  def target_class
53
62
  return @target_class if @target_class
54
63
 
55
- @target_class = target_class_name.constantize if target_class_name
64
+ @target_class = target_class_names[0].constantize if target_class_names && target_class_names.size == 1
56
65
  rescue NameError
57
66
  raise ArgumentError, "Could not find `#{@target_class}` class and no :model_class specified"
58
67
  end
@@ -83,7 +92,7 @@ module Neo4j
83
92
 
84
93
  def relationship_class_type
85
94
  @relationship_class = @relationship_class.constantize if @relationship_class.class == String || @relationship_class == Symbol
86
- @relationship_class._type
95
+ @relationship_class._type.to_sym
87
96
  end
88
97
 
89
98
  def relationship_class_name
@@ -110,11 +119,18 @@ module Neo4j
110
119
  @origin ? origin_association.unique? : !!@unique
111
120
  end
112
121
 
122
+ def create_method
123
+ unique? ? :create_unique : :create
124
+ end
125
+
113
126
  private
114
127
 
115
- def get_direction(relationship_cypher, create)
116
- dir = (create && @direction == :both) ? :out : @direction
117
- case dir
128
+ def association_model_namespace
129
+ Neo4j::Config.association_model_namespace_string
130
+ end
131
+
132
+ def direction_cypher(relationship_cypher, create, reverse = false)
133
+ case get_direction(create, reverse)
118
134
  when :out
119
135
  "-#{relationship_cypher}->"
120
136
  when :in
@@ -124,7 +140,24 @@ module Neo4j
124
140
  end
125
141
  end
126
142
 
127
- def get_relationship_cypher(var, relationship_name_cypher, properties_string)
143
+ def get_direction(create, reverse = false)
144
+ dir = (create && @direction == :both) ? :out : @direction
145
+ if reverse
146
+ case dir
147
+ when :in then :out
148
+ when :out then :in
149
+ else :both
150
+ end
151
+ else
152
+ dir
153
+ end
154
+ end
155
+
156
+ def get_relationship_cypher(var, properties, create)
157
+ relationship_type = relationship_type(create)
158
+ relationship_name_cypher = ":`#{relationship_type}`" if relationship_type
159
+ properties_string = get_properties_string(properties)
160
+
128
161
  "[#{var}#{relationship_name_cypher}#{properties_string}]"
129
162
  end
130
163
 
@@ -146,41 +179,41 @@ module Neo4j
146
179
  private
147
180
 
148
181
  def apply_vars_from_options(options)
149
- @target_class_option = target_class_option(options)
182
+ @target_class_option = target_class_option(options[:model_class])
150
183
  @callbacks = {before: options[:before], after: options[:after]}
151
184
  @origin = options[:origin] && options[:origin].to_sym
152
185
  @relationship_class = options[:rel_class]
153
186
  @relationship_type = options[:type] && options[:type].to_sym
154
- @dependent = options[:dependent]
187
+ @dependent = options[:dependent].try(:to_sym)
155
188
  @unique = options[:unique]
156
189
  end
157
190
 
158
191
  # Return basic details about association as declared in the model
159
192
  # @example
160
- # has_many :in, :bands
193
+ # has_many :in, :bands, type: :has_band
161
194
  def base_declaration
162
195
  "#{type} #{direction.inspect}, #{name.inspect}"
163
196
  end
164
197
 
165
198
  def validate_init_arguments(type, direction, options)
166
199
  validate_option_combinations(options)
200
+ validate_dependent(options[:dependent].try(:to_sym))
167
201
  check_valid_type_and_dir(type, direction)
168
202
  end
169
203
 
170
204
  def check_valid_type_and_dir(type, direction)
171
- fail ArgumentError, "Invalid association type: #{type.inspect} (valid value: :has_many and :has_one)" if not [:has_many, :has_one].include?(type.to_sym)
172
- fail ArgumentError, "Invalid direction: #{direction.inspect} (valid value: :out, :in, and :both)" if not [:out, :in, :both].include?(direction.to_sym)
205
+ fail ArgumentError, "Invalid association type: #{type.inspect} (valid value: :has_many and :has_one)" if ![:has_many, :has_one].include?(type.to_sym)
206
+ fail ArgumentError, "Invalid direction: #{direction.inspect} (valid value: :out, :in, and :both)" if ![:out, :in, :both].include?(direction.to_sym)
173
207
  end
174
208
 
175
209
  def validate_option_combinations(options)
176
- fail ArgumentError, "Cannot specify both :type and :origin (#{base_declaration})" if options[:type] && options[:origin]
177
- fail ArgumentError, "Cannot specify both :type and :rel_class (#{base_declaration})" if options[:type] && options[:rel_class]
178
- fail ArgumentError, "Cannot specify both :origin and :rel_class (#{base_declaration}" if options[:origin] && options[:rel_class]
179
- end
180
-
181
- VALID_DEPENDENT_TYPES = [:delete, :delete_orphans, :destroy_orphans, :destroy, nil]
182
- def validate_dependent(value)
183
- fail ArgumentError, "Invalid dependent value: #{value.inspect}" if not VALID_DEPENDENT_TYPES.include?(value)
210
+ [[:type, :origin],
211
+ [:type, :rel_class],
212
+ [:origin, :rel_class]].each do |key1, key2|
213
+ if options[key1] && options[key2]
214
+ fail ArgumentError, "Cannot specify both :#{key1} and :#{key2} (#{base_declaration})"
215
+ end
216
+ end
184
217
  end
185
218
 
186
219
  # Determine if model class as derived from the association name would be different than the one specified via the model_class key
@@ -197,12 +230,18 @@ module Neo4j
197
230
  def validate_origin!
198
231
  return if not @origin
199
232
 
200
- fail ArgumentError, 'Cannot use :origin without a model_class (implied or explicit)' if not target_class
201
-
202
233
  association = origin_association
203
- fail ArgumentError, "Origin `#{@origin.inspect}` association not found for #{target_class} (specified in #{base_declaration})" if not association
204
234
 
205
- fail ArgumentError, "Origin `#{@origin.inspect}` (specified in #{base_declaration}) has same direction `#{@direction}`)" if @direction == association.direction
235
+ message = case
236
+ when !target_class
237
+ 'Cannot use :origin without a model_class (implied or explicit)'
238
+ when !association
239
+ "Origin `#{@origin.inspect}` association not found for #{target_class} (specified in #{base_declaration})"
240
+ when @direction == association.direction
241
+ "Origin `#{@origin.inspect}` (specified in #{base_declaration}) has same direction `#{@direction}`)"
242
+ end
243
+
244
+ fail ArgumentError, message if message
206
245
  end
207
246
  end
208
247
  end
@@ -20,27 +20,52 @@ module Neo4j::ActiveNode
20
20
  # end
21
21
  # end
22
22
  #
23
+ # @example using already exsting ids that you don't want a constraint added to
24
+ # class Person
25
+ # include Neo4j::ActiveNode
26
+ # property :title
27
+ # validates :title, :presence => true
28
+ # id_property :id, on: :id_builder, constraint: false
29
+ #
30
+ # def id_builder
31
+ # # only need to fill this out if you're gonna write to the db
32
+ # end
33
+ # end
34
+ #
23
35
  module IdProperty
24
36
  extend ActiveSupport::Concern
25
37
 
26
38
 
27
39
  module TypeMethods
28
40
  def define_id_methods(clazz, name, conf)
29
- fail "Expected a Hash, got #{conf.class} (#{conf}) for id_property" unless conf.is_a?(Hash)
41
+ validate_conf!(conf)
42
+
30
43
  if conf[:on]
31
44
  define_custom_method(clazz, name, conf[:on])
32
45
  elsif conf[:auto]
33
- fail "only :uuid auto id_property allowed, got #{conf[:auto]}" unless conf[:auto] == :uuid
34
46
  define_uuid_method(clazz, name)
35
47
  elsif conf.empty?
36
48
  define_property_method(clazz, name)
37
- else
38
- fail "Illegal value #{conf.inspect} for id_property, expected :on or :auto"
39
49
  end
40
50
  end
41
51
 
42
52
  private
43
53
 
54
+ def validate_conf!(conf)
55
+ fail "Expected a Hash, got #{conf.class} (#{conf}) for id_property" if !conf.is_a?(Hash)
56
+
57
+ return if conf[:on]
58
+
59
+ if conf[:auto]
60
+ fail "only :uuid auto id_property allowed, got #{conf[:auto]}" if conf[:auto] != :uuid
61
+ return
62
+ end
63
+
64
+ return if conf.empty?
65
+
66
+ fail "Illegal value #{conf.inspect} for id_property, expected :on or :auto"
67
+ end
68
+
44
69
  def define_property_method(clazz, name)
45
70
  clear_methods(clazz, name)
46
71
 
@@ -90,17 +115,8 @@ module Neo4j::ActiveNode
90
115
  end
91
116
 
92
117
  def clear_methods(clazz, name)
93
- if clazz.method_defined?(name)
94
- clazz.module_eval(%(
95
- undef_method :#{name}
96
- ), __FILE__, __LINE__)
97
- end
98
-
99
- if clazz.attribute_names.include?(name.to_s)
100
- clazz.module_eval(%(
101
- undef_property :#{name}
102
- ), __FILE__, __LINE__)
103
- end
118
+ clazz.module_eval(%(undef_method :#{name}), __FILE__, __LINE__) if clazz.method_defined?(name)
119
+ clazz.module_eval(%(undef_property :#{name}), __FILE__, __LINE__) if clazz.attribute_names.include?(name.to_s)
104
120
  end
105
121
 
106
122
  extend self
@@ -121,22 +137,12 @@ module Neo4j::ActiveNode
121
137
  end
122
138
 
123
139
  def id_property(name, conf = {})
124
- begin
125
- if id_property?
126
- unless mapped_label.uniqueness_constraints[:property_keys].include?([name])
127
- drop_constraint(id_property_name, type: :unique)
128
- end
129
- end
130
- rescue Neo4j::Server::CypherResponse::ResponseError
131
- end
132
-
140
+ id_property_constraint(name)
133
141
  @id_property_info = {name: name, type: conf}
134
142
  TypeMethods.define_id_methods(self, name, conf)
135
- constraint name, type: :unique
143
+ constraint name, type: :unique unless conf[:constraint] == false
136
144
 
137
- self.define_singleton_method(:find_by_id) do |key|
138
- self.where(name => key).first
139
- end
145
+ self.define_singleton_method(:find_by_id) { |key| self.where(name => key).first }
140
146
  end
141
147
 
142
148
  # rubocop:disable Style/PredicateName
@@ -160,6 +166,18 @@ module Neo4j::ActiveNode
160
166
  end
161
167
 
162
168
  alias_method :primary_key, :id_property_name
169
+
170
+ private
171
+
172
+ def id_property_constraint(name)
173
+ if id_property?
174
+ unless mapped_label.uniqueness_constraints[:property_keys].include?([name])
175
+ # Neo4j Embedded throws a crazy error when a constraint can't be dropped
176
+ drop_constraint(id_property_name, type: :unique)
177
+ end
178
+ end
179
+ rescue Neo4j::Server::CypherResponse::ResponseError, Java::OrgNeo4jCypher::CypherExecutionException
180
+ end
163
181
  end
164
182
  end
165
183
  end
@@ -1,19 +1,15 @@
1
1
  module Neo4j::ActiveNode::Initialize
2
2
  extend ActiveSupport::Concern
3
- include Neo4j::Shared::TypeConverters
4
3
  attr_reader :called_by
5
4
 
6
5
  # called when loading the node from the database
7
6
  # @param [Neo4j::Node] persisted_node the node this class wraps
8
7
  # @param [Hash] properties of the persisted node.
9
8
  def init_on_load(persisted_node, properties)
10
- @_association_attributes = self.class.extract_association_attributes!(properties)
9
+ self.class.extract_association_attributes!(properties)
11
10
  @_persisted_obj = persisted_node
12
- @association_cache = {}
13
11
  changed_attributes && changed_attributes.clear
14
- @attributes = attributes.merge(properties.stringify_keys)
15
- self.default_properties = properties
16
- @attributes = convert_properties_to :ruby, @attributes
12
+ @attributes = convert_and_assign_attributes(properties)
17
13
  end
18
14
 
19
15
  # Implements the Neo4j::Node#wrapper and Neo4j::Relationship#wrapper method
@@ -22,4 +18,20 @@ module Neo4j::ActiveNode::Initialize
22
18
  def wrapper
23
19
  self
24
20
  end
21
+
22
+ private
23
+
24
+ def convert_and_assign_attributes(properties)
25
+ @attributes ||= self.class.attributes_nil_hash.dup
26
+ stringify_attributes!(@attributes, properties)
27
+ self.default_properties = properties
28
+ self.class.declared_property_manager.convert_properties_to(self, :ruby, @attributes)
29
+ end
30
+
31
+ def stringify_attributes!(attr, properties)
32
+ properties.each_pair do |k, v|
33
+ key = self.class.declared_property_manager.string_key(k)
34
+ attr[key] = v
35
+ end
36
+ end
25
37
  end
@@ -5,6 +5,19 @@ module Neo4j
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  WRAPPED_CLASSES = []
8
+ MODELS_FOR_LABELS_CACHE = {}
9
+ MODELS_FOR_LABELS_CACHE.clear
10
+
11
+ included do |model|
12
+ def self.inherited(model)
13
+ add_wrapped_class(model)
14
+
15
+ super
16
+ end
17
+
18
+ Neo4j::ActiveNode::Labels.add_wrapped_class(model) unless Neo4j::ActiveNode::Labels._wrapped_classes.include?(model)
19
+ end
20
+
8
21
  class InvalidQueryError < StandardError; end
9
22
  class RecordNotFound < StandardError; end
10
23
 
@@ -32,59 +45,59 @@ module Neo4j
32
45
  @_persisted_obj.remove_label(*label)
33
46
  end
34
47
 
35
- def self.included(klass)
36
- add_wrapped_class(klass)
37
- end
38
-
39
- def self.add_wrapped_class(klass)
40
- _wrapped_classes << klass
41
- @_wrapped_labels = nil
48
+ def self.add_wrapped_class(model)
49
+ _wrapped_classes << model
42
50
  end
43
51
 
44
52
  def self._wrapped_classes
45
53
  Neo4j::ActiveNode::Labels::WRAPPED_CLASSES
46
54
  end
47
55
 
48
- protected
49
-
50
- # Only for testing purpose
51
- # @private
52
- def self._wrapped_labels=(wl)
53
- @_wrapped_labels = (wl)
56
+ def self.model_for_labels(labels)
57
+ MODELS_FOR_LABELS_CACHE[labels] || model_cache(labels)
54
58
  end
55
59
 
56
- def self._wrapped_labels
57
- @_wrapped_labels ||= _wrapped_classes.inject({}) do |ack, clazz|
58
- ack.tap do |a|
59
- a[clazz.mapped_label_name.to_sym] = clazz if clazz.respond_to?(:mapped_label_name)
60
- end
60
+ def self.model_cache(labels)
61
+ models = WRAPPED_CLASSES.select do |model|
62
+ (model.mapped_label_names - labels).size == 0
61
63
  end
64
+
65
+ MODELS_FOR_LABELS_CACHE[labels] = models.max do |model|
66
+ (model.mapped_label_names & labels).size
67
+ end
68
+ end
69
+
70
+ def self.clear_model_for_label_cache
71
+ MODELS_FOR_LABELS_CACHE.clear
62
72
  end
63
73
 
74
+ def self.clear_wrapped_models
75
+ WRAPPED_CLASSES.clear
76
+ end
77
+
78
+ protected
79
+
64
80
  module ClassMethods
65
81
  include Neo4j::ActiveNode::QueryMethods
66
82
 
67
- # Find all nodes/objects of this class
68
- def all
69
- Neo4j::ActiveNode::Query::QueryProxy.new(self, nil, {})
70
- end
71
-
72
83
  # Returns the object with the specified neo4j id.
73
84
  # @param [String,Integer] id of node to find
74
85
  def find(id)
75
86
  map_id = proc { |object| object.respond_to?(:id) ? object.send(:id) : object }
76
87
 
77
- if id.is_a?(Array)
78
- find_by_ids(id.map { |o| map_id.call(o) })
79
- else
80
- find_by_id(map_id.call(id))
81
- end
88
+ result = if id.is_a?(Array)
89
+ find_by_ids(id.map { |o| map_id.call(o) })
90
+ else
91
+ find_by_id(map_id.call(id))
92
+ end
93
+ fail Neo4j::RecordNotFound if result.blank?
94
+ result
82
95
  end
83
96
 
84
97
  # Finds the first record matching the specified conditions. There is no implied ordering so if order matters, you should specify it yourself.
85
98
  # @param Hash args of arguments to find
86
99
  def find_by(values)
87
- self.query_as(:n).where(n: values).limit(1).pluck(:n).first
100
+ all.query_as(:n).where(n: values).limit(1).pluck(:n).first
88
101
  end
89
102
 
90
103
  # Like find_by, except that if no record is found, raises a RecordNotFound error.
@@ -94,14 +107,14 @@ module Neo4j
94
107
 
95
108
  # Deletes all nodes and connected relationships from Cypher.
96
109
  def delete_all
97
- self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`)-[r]-() DELETE n,r")
110
+ self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`) OPTIONAL MATCH n-[r]-() DELETE n,r")
98
111
  self.neo4j_session._query("MATCH (n:`#{mapped_label_name}`) DELETE n")
99
112
  end
100
113
 
101
114
  # Returns each node to Ruby and calls `destroy`. Be careful, as this can be a very slow operation if you have many nodes. It will generate at least
102
115
  # one database query per node in the database, more if callbacks require them.
103
116
  def destroy_all
104
- self.all.each(&:destroy)
117
+ all.each(&:destroy)
105
118
  end
106
119
 
107
120
  # Creates a Neo4j index on given property
@@ -140,8 +153,10 @@ module Neo4j
140
153
  #
141
154
  def constraint(property, constraints)
142
155
  Neo4j::Session.on_session_available do |session|
143
- label = Neo4j::Label.create(mapped_label_name)
144
- label.create_constraint(property, constraints, session)
156
+ unless Neo4j::Label.constraint?(mapped_label_name, property)
157
+ label = Neo4j::Label.create(mapped_label_name)
158
+ label.create_constraint(property, constraints, session)
159
+ end
145
160
  end
146
161
  end
147
162
 
@@ -163,7 +178,7 @@ module Neo4j
163
178
 
164
179
  # @return [Symbol] the label that this class has which corresponds to a Ruby class
165
180
  def mapped_label_name
166
- @mapped_label_name || (self.name.nil? ? object_id.to_s.to_sym : self.name.to_sym)
181
+ @mapped_label_name || label_for_model
167
182
  end
168
183
 
169
184
  # @return [Neo4j::Label] the label for this class
@@ -214,11 +229,30 @@ module Neo4j
214
229
 
215
230
  # rubocop:disable Style/AccessorMethodName
216
231
  def set_mapped_label_name(name)
217
- ActiveSupport::Deprecation.warn 'set_mapped_label_name is deprecated and may be removed from future releases, use self.mapped_label_name= instead.', caller
232
+ ActiveSupport::Deprecation.warn 'set_mapped_label_name is deprecated, use self.mapped_label_name= instead.', caller
218
233
 
219
234
  self.mapped_label_name = name
220
235
  end
221
236
  # rubocop:enable Style/AccessorMethodName
237
+
238
+ private
239
+
240
+ def label_for_model
241
+ (self.name.nil? ? object_id.to_s.to_sym : decorated_label_name)
242
+ end
243
+
244
+ def decorated_label_name
245
+ name = case Neo4j::Config[:module_handling]
246
+ when :demodulize
247
+ self.name.demodulize
248
+ when Proc
249
+ Neo4j::Config[:module_handling].call self.name
250
+ else
251
+ self.name
252
+ end
253
+
254
+ name.to_sym
255
+ end
222
256
  end
223
257
  end
224
258
  end