mongomodel 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +34 -0
  3. data/Rakefile +47 -0
  4. data/bin/console +45 -0
  5. data/lib/mongomodel.rb +92 -0
  6. data/lib/mongomodel/attributes/mongo.rb +40 -0
  7. data/lib/mongomodel/attributes/store.rb +30 -0
  8. data/lib/mongomodel/attributes/typecasting.rb +51 -0
  9. data/lib/mongomodel/concerns/abstract_class.rb +17 -0
  10. data/lib/mongomodel/concerns/activemodel.rb +11 -0
  11. data/lib/mongomodel/concerns/associations.rb +103 -0
  12. data/lib/mongomodel/concerns/associations/base/association.rb +33 -0
  13. data/lib/mongomodel/concerns/associations/base/definition.rb +56 -0
  14. data/lib/mongomodel/concerns/associations/base/proxy.rb +58 -0
  15. data/lib/mongomodel/concerns/associations/belongs_to.rb +68 -0
  16. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +159 -0
  17. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +175 -0
  18. data/lib/mongomodel/concerns/attribute_methods.rb +55 -0
  19. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +29 -0
  20. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +35 -0
  21. data/lib/mongomodel/concerns/attribute_methods/protected.rb +127 -0
  22. data/lib/mongomodel/concerns/attribute_methods/query.rb +22 -0
  23. data/lib/mongomodel/concerns/attribute_methods/read.rb +29 -0
  24. data/lib/mongomodel/concerns/attribute_methods/write.rb +29 -0
  25. data/lib/mongomodel/concerns/attributes.rb +85 -0
  26. data/lib/mongomodel/concerns/callbacks.rb +294 -0
  27. data/lib/mongomodel/concerns/logging.rb +15 -0
  28. data/lib/mongomodel/concerns/pretty_inspect.rb +29 -0
  29. data/lib/mongomodel/concerns/properties.rb +69 -0
  30. data/lib/mongomodel/concerns/record_status.rb +42 -0
  31. data/lib/mongomodel/concerns/timestamps.rb +32 -0
  32. data/lib/mongomodel/concerns/validations.rb +38 -0
  33. data/lib/mongomodel/concerns/validations/associated.rb +46 -0
  34. data/lib/mongomodel/document.rb +20 -0
  35. data/lib/mongomodel/document/callbacks.rb +46 -0
  36. data/lib/mongomodel/document/dynamic_finders.rb +88 -0
  37. data/lib/mongomodel/document/finders.rb +82 -0
  38. data/lib/mongomodel/document/indexes.rb +91 -0
  39. data/lib/mongomodel/document/optimistic_locking.rb +48 -0
  40. data/lib/mongomodel/document/persistence.rb +143 -0
  41. data/lib/mongomodel/document/scopes.rb +161 -0
  42. data/lib/mongomodel/document/validations.rb +68 -0
  43. data/lib/mongomodel/document/validations/uniqueness.rb +78 -0
  44. data/lib/mongomodel/embedded_document.rb +42 -0
  45. data/lib/mongomodel/locale/en.yml +55 -0
  46. data/lib/mongomodel/support/collection.rb +109 -0
  47. data/lib/mongomodel/support/configuration.rb +35 -0
  48. data/lib/mongomodel/support/core_extensions.rb +10 -0
  49. data/lib/mongomodel/support/exceptions.rb +25 -0
  50. data/lib/mongomodel/support/mongo_options.rb +177 -0
  51. data/lib/mongomodel/support/types.rb +35 -0
  52. data/lib/mongomodel/support/types/array.rb +11 -0
  53. data/lib/mongomodel/support/types/boolean.rb +25 -0
  54. data/lib/mongomodel/support/types/custom.rb +38 -0
  55. data/lib/mongomodel/support/types/date.rb +20 -0
  56. data/lib/mongomodel/support/types/float.rb +13 -0
  57. data/lib/mongomodel/support/types/hash.rb +18 -0
  58. data/lib/mongomodel/support/types/integer.rb +13 -0
  59. data/lib/mongomodel/support/types/object.rb +21 -0
  60. data/lib/mongomodel/support/types/string.rb +9 -0
  61. data/lib/mongomodel/support/types/symbol.rb +9 -0
  62. data/lib/mongomodel/support/types/time.rb +12 -0
  63. data/lib/mongomodel/version.rb +3 -0
  64. data/spec/mongomodel/attributes/store_spec.rb +273 -0
  65. data/spec/mongomodel/concerns/activemodel_spec.rb +61 -0
  66. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +153 -0
  67. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +165 -0
  68. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +192 -0
  69. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +46 -0
  70. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +131 -0
  71. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +86 -0
  72. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +27 -0
  73. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +52 -0
  74. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +43 -0
  75. data/spec/mongomodel/concerns/attributes_spec.rb +152 -0
  76. data/spec/mongomodel/concerns/callbacks_spec.rb +90 -0
  77. data/spec/mongomodel/concerns/logging_spec.rb +20 -0
  78. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +68 -0
  79. data/spec/mongomodel/concerns/properties_spec.rb +29 -0
  80. data/spec/mongomodel/concerns/timestamps_spec.rb +170 -0
  81. data/spec/mongomodel/concerns/validations_spec.rb +159 -0
  82. data/spec/mongomodel/document/callbacks_spec.rb +80 -0
  83. data/spec/mongomodel/document/dynamic_finders_spec.rb +183 -0
  84. data/spec/mongomodel/document/finders_spec.rb +231 -0
  85. data/spec/mongomodel/document/indexes_spec.rb +121 -0
  86. data/spec/mongomodel/document/optimistic_locking_spec.rb +57 -0
  87. data/spec/mongomodel/document/persistence_spec.rb +319 -0
  88. data/spec/mongomodel/document/scopes_spec.rb +204 -0
  89. data/spec/mongomodel/document/validations/uniqueness_spec.rb +217 -0
  90. data/spec/mongomodel/document/validations_spec.rb +132 -0
  91. data/spec/mongomodel/document_spec.rb +74 -0
  92. data/spec/mongomodel/embedded_document_spec.rb +66 -0
  93. data/spec/mongomodel/mongomodel_spec.rb +33 -0
  94. data/spec/mongomodel/support/collection_spec.rb +248 -0
  95. data/spec/mongomodel/support/mongo_options_spec.rb +295 -0
  96. data/spec/mongomodel/support/property_spec.rb +83 -0
  97. data/spec/spec.opts +6 -0
  98. data/spec/spec_helper.rb +21 -0
  99. data/spec/specdoc.opts +6 -0
  100. data/spec/support/callbacks.rb +44 -0
  101. data/spec/support/helpers/define_class.rb +24 -0
  102. data/spec/support/helpers/specs_for.rb +11 -0
  103. data/spec/support/matchers/be_a_subclass_of.rb +5 -0
  104. data/spec/support/matchers/respond_to_boolean.rb +17 -0
  105. data/spec/support/matchers/run_callbacks.rb +20 -0
  106. data/spec/support/models.rb +23 -0
  107. data/spec/support/time.rb +6 -0
  108. metadata +232 -0
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2010 Sam Pohlenz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ MongoModel
2
+ ==========
3
+
4
+ MongoModel is a Ruby ORM for interfacing with [MongoDB](http://www.mongodb.org/) databases.
5
+
6
+
7
+ Installation
8
+ ============
9
+
10
+ MongoModel is distributed as a gem. Install with:
11
+
12
+ gem install mongomodel
13
+
14
+
15
+ Sample Usage
16
+ ============
17
+
18
+ require 'mongomodel'
19
+
20
+ MongoModel.configuration = { 'host' => 'localhost', 'database' => 'mydb' }
21
+
22
+ class Article < MongoModel::Document
23
+ property :title, String, :default => 'Untitled'
24
+ property :body, String
25
+ property :published_at, Time, :protected => true
26
+ property :approved, Boolean, :default => false, :protected => true
27
+
28
+ timestamps!
29
+
30
+ validates_presence_of :title, :body
31
+
32
+ belongs_to :author, :class => User
33
+ end
34
+
@@ -0,0 +1,47 @@
1
+ require 'spec/rake/spectask'
2
+ require 'rake/rdoctask'
3
+
4
+ task :default => :spec
5
+
6
+ Spec::Rake::SpecTask.new(:spec) do |t|
7
+ t.libs << 'lib'
8
+ t.spec_opts = ['--options', "#{File.expand_path(File.dirname(__FILE__))}/spec/spec.opts"]
9
+ end
10
+
11
+ namespace :spec do
12
+ desc "Run specs in nested documenting format"
13
+ Spec::Rake::SpecTask.new(:doc) do |t|
14
+ t.libs << 'lib'
15
+ t.spec_opts = ['--options', "#{File.expand_path(File.dirname(__FILE__))}/spec/specdoc.opts"]
16
+ end
17
+ end
18
+
19
+ desc "Generate documentation"
20
+ Rake::RDocTask.new(:doc) do |rdoc|
21
+ rdoc.rdoc_dir = 'doc'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('lib')
24
+ end
25
+
26
+ begin
27
+ require 'jeweler'
28
+ require File.dirname(__FILE__) + "/lib/mongomodel/version"
29
+
30
+ Jeweler::Tasks.new do |gem|
31
+ gem.name = "mongomodel"
32
+ gem.summary = "MongoDB ORM for Ruby/Rails"
33
+ gem.description = "MongoModel is a MongoDB ORM for Ruby/Rails similar to ActiveRecord, DataMapper."
34
+ gem.email = "sam@sampohlenz.com"
35
+ gem.homepage = "http://github.com/spohlenz/mongomodel"
36
+ gem.authors = ["Sam Pohlenz"]
37
+ gem.version = MongoModel::VERSION
38
+
39
+ gem.add_dependency('activesupport', '>= 3.0.pre')
40
+ gem.add_dependency('activemodel', '>= 3.0.pre')
41
+ gem.add_dependency('mongo', '>= 0.18.3')
42
+ end
43
+
44
+ Jeweler::GemcutterTasks.new
45
+ rescue LoadError
46
+ puts "Jeweler not available. Install it with: gem install jeweler"
47
+ end
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ puts "Loading MongoModel sandbox..."
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../lib')
6
+
7
+ require 'irb'
8
+ require 'irb/completion'
9
+
10
+ require 'mongomodel'
11
+
12
+ IRB.setup(nil)
13
+
14
+ IRB.conf[:USE_READLINE] = true
15
+ IRB.conf[:PROMPT_MODE] = :SIMPLE
16
+
17
+ irb = IRB::Irb.new
18
+
19
+ IRB.conf[:MAIN_CONTEXT] = irb.context
20
+
21
+ examples = <<-EXAMPLES
22
+
23
+ class Article < MongoModel::Document
24
+ property :title, String
25
+ property :published, Boolean, :default => false
26
+
27
+ timestamps!
28
+
29
+ default_scope :order => :title.asc
30
+
31
+ named_scope :published, :conditions => { :published => true }
32
+ named_scope :latest, lambda { |num| { :limit => num, :order => 'created_at DESC' } }
33
+ end
34
+
35
+ EXAMPLES
36
+
37
+ puts examples
38
+ irb.context.evaluate(examples, 0)
39
+
40
+ trap("SIGINT") do
41
+ irb.signal_handle
42
+ end
43
+ catch(:IRB_EXIT) do
44
+ irb.eval_input
45
+ end
@@ -0,0 +1,92 @@
1
+ require 'active_support'
2
+ require 'active_model'
3
+
4
+ require 'mongo'
5
+
6
+ require 'mongomodel/support/core_extensions'
7
+ require 'mongomodel/support/exceptions'
8
+ require 'mongomodel/version'
9
+
10
+ require 'active_support/core_ext/module/attribute_accessors'
11
+
12
+ module MongoModel
13
+ autoload :Document, 'mongomodel/document'
14
+ autoload :EmbeddedDocument, 'mongomodel/embedded_document'
15
+
16
+ autoload :Properties, 'mongomodel/concerns/properties'
17
+ autoload :Attributes, 'mongomodel/concerns/attributes'
18
+ autoload :AttributeMethods, 'mongomodel/concerns/attribute_methods'
19
+ autoload :Associations, 'mongomodel/concerns/associations'
20
+ autoload :Validations, 'mongomodel/concerns/validations'
21
+ autoload :Callbacks, 'mongomodel/concerns/callbacks'
22
+ autoload :Logging, 'mongomodel/concerns/logging'
23
+ autoload :Timestamps, 'mongomodel/concerns/timestamps'
24
+ autoload :PrettyInspect, 'mongomodel/concerns/pretty_inspect'
25
+ autoload :RecordStatus, 'mongomodel/concerns/record_status'
26
+ autoload :AbstractClass, 'mongomodel/concerns/abstract_class'
27
+ autoload :ActiveModelCompatibility, 'mongomodel/concerns/activemodel'
28
+
29
+ autoload :MongoOptions, 'mongomodel/support/mongo_options'
30
+ autoload :MongoOrder, 'mongomodel/support/mongo_options'
31
+ autoload :MongoOperator, 'mongomodel/support/mongo_options'
32
+ autoload :Types, 'mongomodel/support/types'
33
+ autoload :Configuration, 'mongomodel/support/configuration'
34
+
35
+ autoload :Collection, 'mongomodel/support/collection'
36
+
37
+ module AttributeMethods
38
+ autoload :Read, 'mongomodel/concerns/attribute_methods/read'
39
+ autoload :Write, 'mongomodel/concerns/attribute_methods/write'
40
+ autoload :Query, 'mongomodel/concerns/attribute_methods/query'
41
+ autoload :BeforeTypeCast, 'mongomodel/concerns/attribute_methods/before_type_cast'
42
+ autoload :Protected, 'mongomodel/concerns/attribute_methods/protected'
43
+ autoload :Dirty, 'mongomodel/concerns/attribute_methods/dirty'
44
+ end
45
+
46
+ module Attributes
47
+ autoload :Store, 'mongomodel/attributes/store'
48
+ autoload :Typecasting, 'mongomodel/attributes/typecasting'
49
+ autoload :Mongo, 'mongomodel/attributes/mongo'
50
+ end
51
+
52
+ module Associations
53
+ module Base
54
+ autoload :Definition, 'mongomodel/concerns/associations/base/definition'
55
+ autoload :Association, 'mongomodel/concerns/associations/base/association'
56
+ autoload :Proxy, 'mongomodel/concerns/associations/base/proxy'
57
+ end
58
+
59
+ autoload :BelongsTo, 'mongomodel/concerns/associations/belongs_to'
60
+ autoload :HasManyByIds, 'mongomodel/concerns/associations/has_many_by_ids'
61
+ autoload :HasManyByForeignKey, 'mongomodel/concerns/associations/has_many_by_foreign_key'
62
+ end
63
+
64
+ module DocumentExtensions
65
+ autoload :Persistence, 'mongomodel/document/persistence'
66
+ autoload :OptimisticLocking, 'mongomodel/document/optimistic_locking'
67
+ autoload :Finders, 'mongomodel/document/finders'
68
+ autoload :DynamicFinders, 'mongomodel/document/dynamic_finders'
69
+ autoload :Indexes, 'mongomodel/document/indexes'
70
+ autoload :Scopes, 'mongomodel/document/scopes'
71
+ autoload :Scope, 'mongomodel/document/scopes'
72
+ autoload :Validations, 'mongomodel/document/validations'
73
+ autoload :Callbacks, 'mongomodel/document/callbacks'
74
+ end
75
+
76
+ mattr_accessor :logger
77
+
78
+ def self.configuration
79
+ @_configuration ||= Configuration.defaults
80
+ end
81
+
82
+ def self.configuration=(config)
83
+ @_database = nil
84
+ @_configuration = Configuration.new(config)
85
+ end
86
+
87
+ def self.database
88
+ @_database ||= configuration.establish_connection
89
+ end
90
+ end
91
+
92
+ I18n.load_path << File.dirname(__FILE__) + '/mongomodel/locale/en.yml'
@@ -0,0 +1,40 @@
1
+ module MongoModel
2
+ module Attributes
3
+ module Mongo
4
+ def to_mongo
5
+ inject({}) do |result, (k, v)|
6
+ property = properties[k]
7
+
8
+ if property
9
+ result[property.as] = property.to_mongo(v)
10
+ else
11
+ converter = Types.converter_for(v.class)
12
+ result[k.to_s] = converter.to_mongo(v)
13
+ end
14
+
15
+ result
16
+ end
17
+ end
18
+
19
+ def from_mongo!(hash)
20
+ hash.each do |k, v|
21
+ property = properties_as[k.to_s]
22
+
23
+ if property
24
+ self[property.name] = property.from_mongo(v)
25
+ else
26
+ self[k.to_sym] = v
27
+ end
28
+ end
29
+ end
30
+
31
+ private
32
+ def properties_as
33
+ @properties_as ||= properties.inject({}) do |result, (name, property)|
34
+ result[property.as] = property
35
+ result
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,30 @@
1
+ require 'active_support/core_ext/module/delegation'
2
+
3
+ module MongoModel
4
+ module Attributes
5
+ class Store < ActiveSupport::OrderedHash
6
+ include Typecasting
7
+ include Mongo
8
+
9
+ attr_reader :instance
10
+ delegate :properties, :to => :instance
11
+
12
+ def initialize(instance)
13
+ super()
14
+ @instance = instance
15
+ set_defaults!
16
+ end
17
+
18
+ def inspect
19
+ "{#{map { |k, v| "#{k.inspect}=>#{v.inspect}"}.join(', ')}}"
20
+ end
21
+
22
+ private
23
+ def set_defaults!
24
+ properties.each do |name, property|
25
+ self[name] = property.default(instance)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,51 @@
1
+ module MongoModel
2
+ module Attributes
3
+ module Typecasting
4
+ def []=(key, value)
5
+ values_before_typecast[key] = value
6
+ super(key, typecast(key, value))
7
+ end
8
+
9
+ # Check if key has a value that typecasts to true.
10
+ #
11
+ # attributes = Attributes::Store.new(:comments_count => Property.new(:comments_count, Integer))
12
+ #
13
+ # attributes[:comments_count] = 0
14
+ # attributes.has?(:comments_count)
15
+ # => false
16
+ #
17
+ # attributes[:comments_count] = 1
18
+ # attributes.has?(:comments_count)
19
+ # => true
20
+ #
21
+ def has?(key)
22
+ value = self[key]
23
+ boolean_typecast(key, value)
24
+ end
25
+
26
+ def before_type_cast(key)
27
+ values_before_typecast[key]
28
+ end
29
+
30
+ private
31
+ def typecast(key, value)
32
+ unless value.nil?
33
+ property = properties[key]
34
+ property ? property.cast(value) : value
35
+ end
36
+ end
37
+
38
+ def boolean_typecast(key, value)
39
+ if property = properties[key]
40
+ value ? property.boolean(value) : false
41
+ else
42
+ !!value
43
+ end
44
+ end
45
+
46
+ def values_before_typecast
47
+ @values_before_typecast ||= {}
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,17 @@
1
+ module MongoModel
2
+ module AbstractClass
3
+ extend ActiveSupport::Concern
4
+
5
+ def inherited(subclass)
6
+ subclass.abstract_class = false
7
+ end
8
+
9
+ module ClassMethods
10
+ attr_accessor :abstract_class
11
+
12
+ def abstract_class?
13
+ abstract_class == true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ module MongoModel
2
+ module ActiveModelCompatibility
3
+ extend ActiveSupport::Concern
4
+
5
+ include ActiveModel::Conversion
6
+
7
+ module ClassMethods
8
+ include ActiveModel::Naming
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,103 @@
1
+ module MongoModel
2
+ module Associations
3
+ extend ActiveSupport::Concern
4
+
5
+ def associations
6
+ @_associations ||= self.class.associations.inject({}) do |result, (name, association)|
7
+ result[name] = association.for(self)
8
+ result
9
+ end
10
+ end
11
+
12
+ module ClassMethods
13
+ def belongs_to(name, options={})
14
+ associations[name] = create_association(BelongsTo, name, options)
15
+ end
16
+
17
+ def has_many(name, options={})
18
+ associations[name] = create_association(has_many_type(options), name, options)
19
+ end
20
+
21
+ def associations
22
+ read_inheritable_attribute(:associations) || write_inheritable_attribute(:associations, {})
23
+ end
24
+
25
+ private
26
+ def has_many_type(options)
27
+ case options[:by]
28
+ when :ids
29
+ HasManyByIds
30
+ when :foreign_key
31
+ HasManyByForeignKey
32
+ else
33
+ ancestors.include?(Document) ? HasManyByForeignKey : HasManyByIds
34
+ end
35
+ end
36
+
37
+ def create_association(type, name, options={})
38
+ type.new(self, name, options).define!
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+
45
+
46
+ #
47
+ # belongs_to :user
48
+ # => property :user_id
49
+ # belongs_to :author, :class_name => 'User'
50
+ # => property :author_id
51
+ # belongs_to :commentable, :polymorphic => true
52
+ # => property :commentable_id
53
+ # => property :commentable_type
54
+ #
55
+
56
+ #
57
+ # has_many :contributors, :class_name => 'User', :foreign_key => :publication_id
58
+ # has_many :comments, :as => :commentable
59
+ # has_many :roles
60
+ #
61
+
62
+
63
+
64
+
65
+ #
66
+ # Documents and EmbeddedDocuments can:
67
+ # - belong to any Document
68
+ # - have many Documents by ids
69
+ #
70
+ # Documents can also:
71
+ # - have many Documents by foreign key
72
+ #
73
+
74
+ # class Author < Document; end
75
+ #
76
+ # class Comment < Document
77
+ # # Creates properties :commentable_id and :commentable_type
78
+ # belongs_to :commentable, :polymorphic => true
79
+ # end
80
+ #
81
+ # class Page < EmbeddedDocument
82
+ # # Creates property :editor_id
83
+ # belongs_to :editor, :class => 'Author'
84
+ #
85
+ # # Creates property :related_article_ids
86
+ # has_many :related_articles, :class => 'Article'
87
+ #
88
+ # # Polymorphic association, uses commentable_id/commentable_type on Comment class
89
+ # has_many :comments, :as => :commentable
90
+ # end
91
+ #
92
+ # class Article < Document
93
+ # # Creates property :author_id
94
+ # belongs_to :author
95
+ #
96
+ # # Creates property :recommended_by_ids
97
+ # has_many :recommended_by, :by => :ids, :class => 'Author'
98
+ #
99
+ # # Creates property :parent_article_id
100
+ # belongs_to :parent_article, :class => 'Article'
101
+ # # Uses parent_article_id property on referenced class
102
+ # has_many :child_articles, :by => :foreign_key, :foreign_key => :parent_article_id, :class => 'Article'
103
+ # end