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.
Files changed (60) hide show
  1. data/CONTRIBUTORS +1 -0
  2. data/Gemfile +1 -0
  3. data/README.rdoc +1 -0
  4. data/lib/neo4j/algo/algo.rb +5 -5
  5. data/lib/neo4j/database.rb +1 -1
  6. data/lib/neo4j/has_n/class_methods.rb +5 -6
  7. data/lib/neo4j/has_n/decl_relationship_dsl.rb +32 -21
  8. data/lib/neo4j/has_n/mapping.rb +4 -5
  9. data/lib/neo4j/index/indexer.rb +21 -17
  10. data/lib/neo4j/index/indexer_registry.rb +1 -0
  11. data/lib/neo4j/index/lucene_query.rb +1 -1
  12. data/lib/neo4j/jars/core/neo4j-backup-1.3.jar +0 -0
  13. data/lib/neo4j/jars/core/{neo4j-graph-algo-1.3.M03.jar → neo4j-graph-algo-1.3.jar} +0 -0
  14. data/lib/neo4j/jars/core/neo4j-kernel-1.3.jar +0 -0
  15. data/lib/neo4j/jars/core/neo4j-lucene-index-1.3.jar +0 -0
  16. data/lib/neo4j/jars/ha/neo4j-com-1.3.jar +0 -0
  17. data/lib/neo4j/jars/ha/neo4j-ha-1.3.jar +0 -0
  18. data/lib/neo4j/jars/ha/neo4j-jmx-1.3.jar +0 -0
  19. data/lib/neo4j/jars/ha/neo4j-management-1.3.jar +0 -0
  20. data/lib/neo4j/jars/ha/{neo4j-shell-1.3.M03.jar → neo4j-shell-1.3.jar} +0 -0
  21. data/lib/neo4j/neo4j.rb +1 -1
  22. data/lib/neo4j/node.rb +2 -3
  23. data/lib/neo4j/node_mixin/node_mixin.rb +5 -0
  24. data/lib/neo4j/property/class_methods.rb +6 -10
  25. data/lib/neo4j/property/property.rb +0 -2
  26. data/lib/neo4j/rails/attributes.rb +10 -8
  27. data/lib/neo4j/rails/callbacks.rb +1 -1
  28. data/lib/neo4j/rails/finders.rb +1 -1
  29. data/lib/neo4j/rails/lucene_connection_closer.rb +1 -3
  30. data/lib/neo4j/rails/mapping/property.rb +112 -35
  31. data/lib/neo4j/rails/model.rb +10 -0
  32. data/lib/neo4j/rails/persistence.rb +10 -4
  33. data/lib/neo4j/rails/rails.rb +6 -2
  34. data/lib/neo4j/rails/rel_persistence.rb +231 -0
  35. data/lib/neo4j/rails/relationship.rb +126 -0
  36. data/lib/neo4j/rails/relationships/node_dsl.rb +91 -0
  37. data/lib/neo4j/rails/relationships/relationships.rb +47 -40
  38. data/lib/neo4j/rails/relationships/rels_dsl.rb +82 -0
  39. data/lib/neo4j/rails/relationships/storage.rb +161 -0
  40. data/lib/neo4j/rails/serialization.rb +1 -1
  41. data/lib/neo4j/rails/validations/associated.rb +53 -0
  42. data/lib/neo4j/rails/validations.rb +2 -3
  43. data/lib/neo4j/relationship.rb +3 -3
  44. data/lib/neo4j/relationship_mixin/relationship_mixin.rb +5 -1
  45. data/lib/neo4j/rels/traverser.rb +12 -12
  46. data/lib/neo4j/rule/rule_node.rb +2 -1
  47. data/lib/neo4j/to_java.rb +0 -4
  48. data/lib/neo4j/traversal/traverser.rb +24 -3
  49. data/lib/neo4j/type_converters/type_converters.rb +59 -6
  50. data/lib/neo4j/version.rb +1 -1
  51. data/lib/neo4j.rb +10 -8
  52. metadata +21 -16
  53. data/lib/neo4j/jars/core/neo4j-backup-1.3.M03.jar +0 -0
  54. data/lib/neo4j/jars/core/neo4j-kernel-1.3.M03.jar +0 -0
  55. data/lib/neo4j/jars/core/neo4j-lucene-index-1.3.M03.jar +0 -0
  56. data/lib/neo4j/jars/ha/neo4j-com-1.3.M03.jar +0 -0
  57. data/lib/neo4j/jars/ha/neo4j-ha-1.3.M03.jar +0 -0
  58. data/lib/neo4j/jars/ha/neo4j-management-1.3.M03.jar +0 -0
  59. data/lib/neo4j/rails/relationships/mapper.rb +0 -103
  60. data/lib/neo4j/rails/relationships/relationship.rb +0 -30
@@ -1,51 +1,128 @@
1
1
  module Neo4j
2
- module Rails
3
- module Mapping
4
- module Property
5
- extend ActiveSupport::Concern
6
-
7
- module ClassMethods
8
- # Handles options for the property
9
- #
10
- # Set the property type :type => Time
11
- # Set a default :default => "default"
12
- # Property must be there :null => false
13
- # Property has a length limit :limit => 128
14
- def property(*args)
15
- options = args.extract_options!
16
- args.each do |property_sym|
17
- property_setup(property_sym, options)
18
- end
19
- end
20
-
21
- protected
22
- def property_setup(property, options)
23
- _decl_props[property] = options
24
- handle_property_options_for(property, options)
25
- define_property_methods_for(property, options)
26
- end
27
-
28
- def handle_property_options_for(property, options)
29
- attribute_defaults[property.to_s] = options[:default] if options.has_key?(:default)
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
- RUBY
45
- end
46
-
47
- unless method_defined?("#{property}=".to_sym)
48
- class_eval <<-RUBY, __FILE__, __LINE__
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
@@ -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 { |o| o.save }
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 { |o| o.save! }
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.
@@ -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/mapper'
16
- require 'neo4j/rails/relationships/relationship'
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