activegraph 11.0.0.beta.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2016 -0
  3. data/CONTRIBUTORS +12 -0
  4. data/Gemfile +24 -0
  5. data/README.md +111 -0
  6. data/activegraph.gemspec +52 -0
  7. data/bin/rake +17 -0
  8. data/config/locales/en.yml +5 -0
  9. data/config/neo4j/add_classnames.yml +1 -0
  10. data/config/neo4j/config.yml +35 -0
  11. data/lib/active_graph.rb +123 -0
  12. data/lib/active_graph/ansi.rb +14 -0
  13. data/lib/active_graph/attribute_set.rb +32 -0
  14. data/lib/active_graph/base.rb +77 -0
  15. data/lib/active_graph/class_arguments.rb +39 -0
  16. data/lib/active_graph/config.rb +135 -0
  17. data/lib/active_graph/core.rb +14 -0
  18. data/lib/active_graph/core/connection_failed_error.rb +6 -0
  19. data/lib/active_graph/core/cypher_error.rb +37 -0
  20. data/lib/active_graph/core/entity.rb +11 -0
  21. data/lib/active_graph/core/instrumentable.rb +37 -0
  22. data/lib/active_graph/core/label.rb +135 -0
  23. data/lib/active_graph/core/logging.rb +44 -0
  24. data/lib/active_graph/core/node.rb +15 -0
  25. data/lib/active_graph/core/querable.rb +41 -0
  26. data/lib/active_graph/core/query.rb +485 -0
  27. data/lib/active_graph/core/query_builder.rb +18 -0
  28. data/lib/active_graph/core/query_clauses.rb +727 -0
  29. data/lib/active_graph/core/query_ext.rb +24 -0
  30. data/lib/active_graph/core/query_find_in_batches.rb +46 -0
  31. data/lib/active_graph/core/record.rb +51 -0
  32. data/lib/active_graph/core/result.rb +31 -0
  33. data/lib/active_graph/core/schema.rb +65 -0
  34. data/lib/active_graph/core/schema_errors.rb +12 -0
  35. data/lib/active_graph/core/wrappable.rb +30 -0
  36. data/lib/active_graph/errors.rb +59 -0
  37. data/lib/active_graph/lazy_attribute_hash.rb +38 -0
  38. data/lib/active_graph/migration.rb +148 -0
  39. data/lib/active_graph/migrations.rb +27 -0
  40. data/lib/active_graph/migrations/base.rb +77 -0
  41. data/lib/active_graph/migrations/check_pending.rb +20 -0
  42. data/lib/active_graph/migrations/helpers.rb +105 -0
  43. data/lib/active_graph/migrations/helpers/id_property.rb +72 -0
  44. data/lib/active_graph/migrations/helpers/relationships.rb +66 -0
  45. data/lib/active_graph/migrations/helpers/schema.rb +63 -0
  46. data/lib/active_graph/migrations/migration_file.rb +24 -0
  47. data/lib/active_graph/migrations/runner.rb +195 -0
  48. data/lib/active_graph/migrations/schema.rb +64 -0
  49. data/lib/active_graph/migrations/schema_migration.rb +14 -0
  50. data/lib/active_graph/model_schema.rb +139 -0
  51. data/lib/active_graph/node.rb +110 -0
  52. data/lib/active_graph/node/callbacks.rb +8 -0
  53. data/lib/active_graph/node/dependent.rb +11 -0
  54. data/lib/active_graph/node/dependent/association_methods.rb +49 -0
  55. data/lib/active_graph/node/dependent/query_proxy_methods.rb +52 -0
  56. data/lib/active_graph/node/dependent_callbacks.rb +31 -0
  57. data/lib/active_graph/node/enum.rb +26 -0
  58. data/lib/active_graph/node/has_n.rb +602 -0
  59. data/lib/active_graph/node/has_n/association.rb +278 -0
  60. data/lib/active_graph/node/has_n/association/rel_factory.rb +61 -0
  61. data/lib/active_graph/node/has_n/association/rel_wrapper.rb +23 -0
  62. data/lib/active_graph/node/has_n/association_cypher_methods.rb +108 -0
  63. data/lib/active_graph/node/id_property.rb +224 -0
  64. data/lib/active_graph/node/id_property/accessor.rb +62 -0
  65. data/lib/active_graph/node/initialize.rb +21 -0
  66. data/lib/active_graph/node/labels.rb +207 -0
  67. data/lib/active_graph/node/labels/index.rb +37 -0
  68. data/lib/active_graph/node/labels/reloading.rb +21 -0
  69. data/lib/active_graph/node/node_list_formatter.rb +13 -0
  70. data/lib/active_graph/node/node_wrapper.rb +54 -0
  71. data/lib/active_graph/node/orm_adapter.rb +82 -0
  72. data/lib/active_graph/node/persistence.rb +186 -0
  73. data/lib/active_graph/node/property.rb +60 -0
  74. data/lib/active_graph/node/query.rb +76 -0
  75. data/lib/active_graph/node/query/query_proxy.rb +367 -0
  76. data/lib/active_graph/node/query/query_proxy_eager_loading.rb +177 -0
  77. data/lib/active_graph/node/query/query_proxy_eager_loading/association_tree.rb +75 -0
  78. data/lib/active_graph/node/query/query_proxy_enumerable.rb +110 -0
  79. data/lib/active_graph/node/query/query_proxy_find_in_batches.rb +19 -0
  80. data/lib/active_graph/node/query/query_proxy_link.rb +139 -0
  81. data/lib/active_graph/node/query/query_proxy_methods.rb +303 -0
  82. data/lib/active_graph/node/query/query_proxy_methods_of_mass_updating.rb +99 -0
  83. data/lib/active_graph/node/query_methods.rb +68 -0
  84. data/lib/active_graph/node/reflection.rb +86 -0
  85. data/lib/active_graph/node/rels.rb +11 -0
  86. data/lib/active_graph/node/scope.rb +166 -0
  87. data/lib/active_graph/node/unpersisted.rb +48 -0
  88. data/lib/active_graph/node/validations.rb +59 -0
  89. data/lib/active_graph/paginated.rb +27 -0
  90. data/lib/active_graph/railtie.rb +108 -0
  91. data/lib/active_graph/relationship.rb +68 -0
  92. data/lib/active_graph/relationship/callbacks.rb +21 -0
  93. data/lib/active_graph/relationship/initialize.rb +28 -0
  94. data/lib/active_graph/relationship/persistence.rb +133 -0
  95. data/lib/active_graph/relationship/persistence/query_factory.rb +95 -0
  96. data/lib/active_graph/relationship/property.rb +92 -0
  97. data/lib/active_graph/relationship/query.rb +99 -0
  98. data/lib/active_graph/relationship/rel_wrapper.rb +31 -0
  99. data/lib/active_graph/relationship/related_node.rb +87 -0
  100. data/lib/active_graph/relationship/types.rb +80 -0
  101. data/lib/active_graph/relationship/validations.rb +8 -0
  102. data/lib/active_graph/schema/operation.rb +102 -0
  103. data/lib/active_graph/shared.rb +48 -0
  104. data/lib/active_graph/shared/attributes.rb +217 -0
  105. data/lib/active_graph/shared/callbacks.rb +66 -0
  106. data/lib/active_graph/shared/cypher.rb +37 -0
  107. data/lib/active_graph/shared/declared_properties.rb +204 -0
  108. data/lib/active_graph/shared/declared_property.rb +109 -0
  109. data/lib/active_graph/shared/declared_property/index.rb +37 -0
  110. data/lib/active_graph/shared/enum.rb +167 -0
  111. data/lib/active_graph/shared/filtered_hash.rb +79 -0
  112. data/lib/active_graph/shared/identity.rb +34 -0
  113. data/lib/active_graph/shared/initialize.rb +65 -0
  114. data/lib/active_graph/shared/marshal.rb +23 -0
  115. data/lib/active_graph/shared/mass_assignment.rb +63 -0
  116. data/lib/active_graph/shared/permitted_attributes.rb +28 -0
  117. data/lib/active_graph/shared/persistence.rb +272 -0
  118. data/lib/active_graph/shared/property.rb +249 -0
  119. data/lib/active_graph/shared/query_factory.rb +122 -0
  120. data/lib/active_graph/shared/rel_type_converters.rb +43 -0
  121. data/lib/active_graph/shared/serialized_properties.rb +30 -0
  122. data/lib/active_graph/shared/type_converters.rb +439 -0
  123. data/lib/active_graph/shared/typecasted_attributes.rb +99 -0
  124. data/lib/active_graph/shared/typecaster.rb +53 -0
  125. data/lib/active_graph/shared/validations.rb +44 -0
  126. data/lib/active_graph/tasks/migration.rake +204 -0
  127. data/lib/active_graph/timestamps.rb +11 -0
  128. data/lib/active_graph/timestamps/created.rb +9 -0
  129. data/lib/active_graph/timestamps/updated.rb +9 -0
  130. data/lib/active_graph/transaction.rb +22 -0
  131. data/lib/active_graph/transactions.rb +57 -0
  132. data/lib/active_graph/type_converters.rb +7 -0
  133. data/lib/active_graph/undeclared_properties.rb +53 -0
  134. data/lib/active_graph/version.rb +3 -0
  135. data/lib/active_graph/wrapper.rb +4 -0
  136. data/lib/rails/generators/active_graph/migration/migration_generator.rb +16 -0
  137. data/lib/rails/generators/active_graph/migration/templates/migration.erb +9 -0
  138. data/lib/rails/generators/active_graph/model/model_generator.rb +89 -0
  139. data/lib/rails/generators/active_graph/model/templates/migration.erb +11 -0
  140. data/lib/rails/generators/active_graph/model/templates/model.erb +15 -0
  141. data/lib/rails/generators/active_graph/upgrade_v8/templates/migration.erb +17 -0
  142. data/lib/rails/generators/active_graph/upgrade_v8/upgrade_v8_generator.rb +34 -0
  143. data/lib/rails/generators/active_graph_generator.rb +121 -0
  144. metadata +423 -0
@@ -0,0 +1,8 @@
1
+ module ActiveGraph
2
+ module Relationship
3
+ module Validations
4
+ extend ActiveSupport::Concern
5
+ include ActiveGraph::Shared::Validations
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,102 @@
1
+ module ActiveGraph
2
+ module Schema
3
+ class Operation
4
+ attr_reader :label, :property, :options
5
+
6
+ def initialize(label, property, options = default_options)
7
+ @label = if label.is_a?(ActiveGraph::Core::Label)
8
+ label
9
+ else
10
+ ActiveGraph::Core::Label.new(label)
11
+ end
12
+
13
+ @property = property.to_sym
14
+ @options = options
15
+ end
16
+
17
+ def self.incompatible_operation_classes
18
+ []
19
+ end
20
+
21
+ def label_object
22
+ label
23
+ end
24
+
25
+ def create!
26
+ drop_incompatible!
27
+ return if exist?
28
+ schema_query(:"create_#{type}")
29
+ end
30
+
31
+ def incompatible_operation_classes
32
+ self.class.incompatible_operation_classes
33
+ end
34
+
35
+ def drop!
36
+ schema_query(:"drop_#{type}")
37
+ end
38
+
39
+ def drop_incompatible!
40
+ incompatible_operation_classes.each do |clazz|
41
+ operation = clazz.new(@label, property)
42
+ operation.drop! if operation.exist?
43
+ end
44
+ end
45
+
46
+ def exist?
47
+ fail 'Abstract class, not implemented'
48
+ end
49
+
50
+ def default_options
51
+ {}
52
+ end
53
+
54
+ def type
55
+ fail 'Abstract class, not implemented'
56
+ end
57
+
58
+ private
59
+
60
+ def schema_query(method)
61
+ label.send(method, property, options)
62
+ end
63
+ end
64
+
65
+ class ExactIndexOperation < ActiveGraph::Schema::Operation
66
+ def self.incompatible_operation_classes
67
+ [UniqueConstraintOperation]
68
+ end
69
+
70
+ def type
71
+ 'index'
72
+ end
73
+
74
+ def exist?
75
+ label.index?(property)
76
+ end
77
+ end
78
+
79
+ class UniqueConstraintOperation < ActiveGraph::Schema::Operation
80
+ def self.incompatible_operation_classes
81
+ [ExactIndexOperation]
82
+ end
83
+
84
+ def type
85
+ 'uniqueness_constraint'
86
+ end
87
+
88
+ def create!
89
+ return if exist?
90
+ super
91
+ end
92
+
93
+ def exist?
94
+ label.uniqueness_constraint?(property)
95
+ end
96
+
97
+ def default_options
98
+ {type: :unique}
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,48 @@
1
+ module ActiveGraph
2
+ module Shared
3
+ extend ActiveSupport::Concern
4
+ extend ActiveModel::Naming
5
+
6
+ include ActiveModel::Conversion
7
+ begin
8
+ include ActiveModel::Serializers::Xml
9
+ rescue NameError; end # rubocop:disable Lint/HandleExceptions
10
+ include ActiveModel::Serializers::JSON
11
+
12
+ module ClassMethods
13
+ # This should be used everywhere. Should make it easy
14
+ # to support a driver-per-model system
15
+ def neo4j_query(*args)
16
+ ActiveGraph::Base.query(*args)
17
+ end
18
+
19
+ def new_query
20
+ ActiveGraph::Base.new_query
21
+ end
22
+ end
23
+
24
+ included do
25
+ self.include_root_in_json = ActiveGraph::Config.include_root_in_json
26
+ @_declared_properties ||= ActiveGraph::Shared::DeclaredProperties.new(self)
27
+
28
+ def self.i18n_scope
29
+ :neo4j
30
+ end
31
+
32
+ def self.inherited(other)
33
+ attributes.each_pair do |k, v|
34
+ other.inherit_property k.to_sym, v.clone, declared_properties[k].options
35
+ end
36
+ super
37
+ end
38
+ end
39
+
40
+ def declared_properties
41
+ self.class.declared_properties
42
+ end
43
+
44
+ def neo4j_query(*args)
45
+ self.class.neo4j_query(*args)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,217 @@
1
+ module ActiveGraph::Shared
2
+ # Attributes provides a set of class methods for defining an attributes
3
+ # schema and instance methods for reading and writing attributes.
4
+ #
5
+ # @example Usage
6
+ # class Person
7
+ # include ActiveGraph::Shared::Attributes
8
+ # attribute :name
9
+ # end
10
+ #
11
+ # person = Person.new
12
+ # person.name = "Ben Poweski"
13
+ #
14
+ # Originally part of ActiveAttr, https://github.com/cgriego/active_attr
15
+ module Attributes
16
+ extend ActiveSupport::Concern
17
+ include ActiveModel::AttributeMethods
18
+
19
+ # Methods deprecated on the Object class which can be safely overridden
20
+ DEPRECATED_OBJECT_METHODS = %w(id type)
21
+
22
+ included do
23
+ attribute_method_suffix '' if attribute_method_matchers.none? { |matcher| matcher.prefix == '' && matcher.suffix == '' }
24
+ attribute_method_suffix '='
25
+ attribute_method_suffix '?'
26
+ end
27
+
28
+ # Performs equality checking on the result of attributes and its type.
29
+ #
30
+ # @example Compare for equality.
31
+ # model == other
32
+ #
33
+ # @param [ActiveAttr::Attributes, Object] other The other model to compare
34
+ #
35
+ # @return [true, false] True if attributes are equal and other is instance
36
+ # of the same Class, false if not.
37
+ def ==(other)
38
+ return false unless other.instance_of? self.class
39
+ attributes == other.attributes
40
+ end
41
+
42
+ # Returns a Hash of all attributes
43
+ #
44
+ # @example Get attributes
45
+ # person.attributes # => {"name"=>"Ben Poweski"}
46
+ #
47
+ # @return [Hash{String => Object}] The Hash of all attributes
48
+ def attributes
49
+ attributes_map { |name| send name }
50
+ end
51
+
52
+ # Write a single attribute to the model's attribute hash.
53
+ #
54
+ # @example Write the attribute with write_attribute
55
+ # person.write_attribute(:name, "Benjamin")
56
+ # @example Write an attribute with bracket syntax
57
+ # person[:name] = "Benjamin"
58
+ #
59
+ # @param [String, Symbol, #to_s] name The name of the attribute to update.
60
+ # @param [Object] value The value to set for the attribute.
61
+ #
62
+ # @raise [UnknownAttributeError] if the attribute is unknown
63
+ def write_attribute(name, value)
64
+ fail ActiveGraph::UnknownAttributeError, "unknown attribute: #{name}" if !respond_to? "#{name}="
65
+
66
+ send "#{name}=", value
67
+ end
68
+ alias []= write_attribute
69
+
70
+ def query_attribute(name)
71
+ fail ActiveGraph::UnknownAttributeError, "unknown attribute: #{name}" if !respond_to? "#{name}?"
72
+
73
+ send "#{name}?"
74
+ end
75
+
76
+ private
77
+
78
+ # Read an attribute from the attributes hash
79
+ def attribute(name)
80
+ @attributes ||= ActiveGraph::AttributeSet.new({}, self.class.attributes.keys)
81
+ @attributes.fetch_value(name.to_s)
82
+ end
83
+
84
+ # Write an attribute to the attributes hash
85
+ def attribute=(name, value)
86
+ @attributes ||= ActiveGraph::AttributeSet.new({}, self.class.attributes.keys)
87
+ @attributes.write_cast_value(name, value)
88
+ value
89
+ end
90
+
91
+ # Maps all attributes using the given block
92
+ #
93
+ # @example Stringify attributes
94
+ # person.attributes_map { |name| send(name).to_s }
95
+ #
96
+ # @yield [name] block called to return hash value
97
+ # @yieldparam [String] name The name of the attribute to map.
98
+ #
99
+ # @return [Hash{String => Object}] The Hash of mapped attributes
100
+ def attributes_map
101
+ Hash[self.class.attribute_names.map { |name| [name, yield(name)] }]
102
+ end
103
+
104
+ def attribute?(name)
105
+ ActiveGraph::Shared::TypeConverters::BooleanConverter.to_ruby(read_attribute(name))
106
+ end
107
+
108
+ module ClassMethods
109
+ # Defines an attribute
110
+ #
111
+ # For each attribute that is defined, a getter and setter will be
112
+ # added as an instance method to the model. An
113
+ # {AttributeDefinition} instance will be added to result of the
114
+ # attributes class method.
115
+ #
116
+ # @example Define an attribute.
117
+ # attribute :name
118
+ #
119
+ # @param (see AttributeDefinition#initialize)
120
+ #
121
+ # @raise [DangerousAttributeError] if the attribute name conflicts with
122
+ # existing methods
123
+ #
124
+ # @return [AttributeDefinition] Attribute's definition
125
+ def attribute(name)
126
+ fail ActiveGraph::DangerousAttributeError, %(an attribute method named "#{name}" would conflict with an existing method) if dangerous_attribute?(name)
127
+
128
+ attribute!(name)
129
+ end
130
+
131
+ # Returns an Array of attribute names as Strings
132
+ #
133
+ # @example Get attribute names
134
+ # Person.attribute_names
135
+ #
136
+ # @return [Array<String>] The attribute names
137
+ def attribute_names
138
+ attributes.keys
139
+ end
140
+
141
+ # Returns a Hash of AttributeDefinition instances
142
+ #
143
+ # @example Get attribute definitions
144
+ # Person.attributes
145
+ #
146
+ # @return [ActiveSupport::HashWithIndifferentAccess{String => ActiveGraph::Shared::AttributeDefinition}]
147
+ # The Hash of AttributeDefinition instances
148
+ def attributes
149
+ @attributes ||= ActiveSupport::HashWithIndifferentAccess.new
150
+ end
151
+
152
+ # Determine if a given attribute name is dangerous
153
+ #
154
+ # Some attribute names can cause conflicts with existing methods
155
+ # on an object. For example, an attribute named "timeout" would
156
+ # conflict with the timeout method that Ruby's Timeout library
157
+ # mixes into Object.
158
+ #
159
+ # @example Testing a harmless attribute
160
+ # Person.dangerous_attribute? :name #=> false
161
+ #
162
+ # @example Testing a dangerous attribute
163
+ # Person.dangerous_attribute? :nil #=> "nil?"
164
+ #
165
+ # @param name Attribute name
166
+ #
167
+ # @return [false, String] False or the conflicting method name
168
+ def dangerous_attribute?(name)
169
+ methods = instance_methods
170
+
171
+ attribute_methods(name).detect do |method_name|
172
+ !DEPRECATED_OBJECT_METHODS.include?(method_name.to_s) && methods.include?(method_name)
173
+ end unless attribute_names.include? name.to_s
174
+ end
175
+
176
+ # Returns the class name plus its attribute names
177
+ #
178
+ # @example Inspect the model's definition.
179
+ # Person.inspect
180
+ #
181
+ # @return [String] Human-readable presentation of the attributes
182
+ def inspect
183
+ inspected_attributes = attribute_names.sort
184
+ attributes_list = "(#{inspected_attributes.join(', ')})" unless inspected_attributes.empty?
185
+ "#{name}#{attributes_list}"
186
+ end
187
+
188
+ protected
189
+
190
+ # Assign a set of attribute definitions, used when subclassing models
191
+ #
192
+ # @param [Array<ActiveGraph::Shared::DeclaredProperties>] attributes The Array of
193
+ # AttributeDefinition instances
194
+ def attributes=(attributes)
195
+ @attributes = attributes
196
+ end
197
+
198
+ # Overrides ActiveModel::AttributeMethods to backport 3.2 fix
199
+ def instance_method_already_implemented?(method_name)
200
+ generated_attribute_methods.method_defined?(method_name)
201
+ end
202
+
203
+ private
204
+
205
+ # Expand an attribute name into its generated methods names
206
+ def attribute_methods(name)
207
+ attribute_method_matchers.map { |matcher| matcher.method_name name }
208
+ end
209
+
210
+ # Ruby inherited hook to assign superclass attributes to subclasses
211
+ def inherited(subclass)
212
+ super
213
+ subclass.attributes = attributes.dup
214
+ end
215
+ end
216
+ end
217
+ end
@@ -0,0 +1,66 @@
1
+ module ActiveGraph
2
+ module Shared
3
+ module Callbacks #:nodoc:
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ include ActiveModel::Callbacks
8
+ end
9
+
10
+ included do
11
+ include ActiveModel::Validations::Callbacks
12
+ # after_find is triggered by the `find` method defined in lib/active_graph/node/id_property.rb
13
+ define_model_callbacks :initialize, :find, only: :after
14
+ define_model_callbacks :create_commit, :update_commit, :destroy_commit, only: :after
15
+ define_model_callbacks :save, :create, :update, :destroy, :touch
16
+ end
17
+
18
+ def initialize(args = nil)
19
+ run_callbacks(:initialize) { super }
20
+ end
21
+
22
+ def destroy #:nodoc:
23
+ ActiveGraph::Base.validating_transaction do |tx|
24
+ tx.after_commit { run_callbacks(:destroy_commit) {} }
25
+ run_callbacks(:destroy) { super }
26
+ end
27
+ rescue
28
+ @_deleted = false
29
+ @attributes = @attributes.dup
30
+ raise
31
+ end
32
+
33
+ def touch #:nodoc:
34
+ run_callbacks(:touch) { super }
35
+ end
36
+
37
+ # Allows you to perform a callback if a condition is not satisfied.
38
+ # @param [Symbol] kind The callback type to execute unless the guard is true
39
+ # @param [TrueClass,FalseClass] guard When this value is true, the block is yielded without executing callbacks.
40
+ def conditional_callback(kind, guard)
41
+ return yield if guard
42
+ run_callbacks(kind) { yield }
43
+ end
44
+
45
+ private
46
+
47
+ def create_or_update #:nodoc:
48
+ run_callbacks(:save) { super }
49
+ end
50
+
51
+ def create_model #:nodoc:
52
+ ActiveGraph::Base.transaction do |tx|
53
+ tx.after_commit { run_callbacks(:create_commit) {} }
54
+ run_callbacks(:create) { super }
55
+ end
56
+ end
57
+
58
+ def update_model(*) #:nodoc:
59
+ ActiveGraph::Base.transaction do |tx|
60
+ tx.after_commit { run_callbacks(:update_commit) {} }
61
+ run_callbacks(:update) { super }
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,37 @@
1
+ module ActiveGraph::Shared
2
+ module Cypher
3
+ module CreateMethod
4
+ def create_method
5
+ creates_unique? ? :create_unique : :create
6
+ end
7
+
8
+ def creates_unique(option = :none)
9
+ option = :none if option == true
10
+ @creates_unique = option
11
+ end
12
+
13
+ def creates_unique_option
14
+ @creates_unique || :none
15
+ end
16
+
17
+ def creates_unique?
18
+ !!@creates_unique
19
+ end
20
+ alias unique? creates_unique?
21
+ end
22
+
23
+ module RelIdentifiers
24
+ extend ActiveSupport::Concern
25
+
26
+ [:from_node, :to_node, :rel].each do |element|
27
+ define_method("#{element}_identifier") do
28
+ instance_variable_get(:"@#{element}_identifier") || element
29
+ end
30
+
31
+ define_method("#{element}_identifier=") do |id|
32
+ instance_variable_set(:"@#{element}_identifier", id.to_sym)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end