active_mongoid 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.coveralls.yml +1 -0
  4. data/.gitignore +22 -0
  5. data/.ruby_gemset +1 -0
  6. data/.ruby_version +1 -0
  7. data/.travis.yml +11 -0
  8. data/Appraisals +7 -0
  9. data/Gemfile +4 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +198 -0
  12. data/Rakefile +7 -0
  13. data/active_mongoid.gemspec +36 -0
  14. data/gemfiles/mongoid_2.8.gemfile +7 -0
  15. data/gemfiles/mongoid_2.8.gemfile.lock +105 -0
  16. data/gemfiles/mongoid_3.1.gemfile +7 -0
  17. data/gemfiles/mongoid_3.1.gemfile.lock +108 -0
  18. data/lib/active_mongoid.rb +8 -0
  19. data/lib/active_mongoid/associations.rb +82 -0
  20. data/lib/active_mongoid/associations/binding.rb +77 -0
  21. data/lib/active_mongoid/associations/builder.rb +26 -0
  22. data/lib/active_mongoid/associations/builders/in.rb +17 -0
  23. data/lib/active_mongoid/associations/builders/many.rb +15 -0
  24. data/lib/active_mongoid/associations/builders/one.rb +15 -0
  25. data/lib/active_mongoid/associations/document_relation/accessors.rb +100 -0
  26. data/lib/active_mongoid/associations/document_relation/associations.rb +33 -0
  27. data/lib/active_mongoid/associations/document_relation/auto_save.rb +31 -0
  28. data/lib/active_mongoid/associations/document_relation/bindings/in.rb +48 -0
  29. data/lib/active_mongoid/associations/document_relation/bindings/many.rb +19 -0
  30. data/lib/active_mongoid/associations/document_relation/bindings/one.rb +19 -0
  31. data/lib/active_mongoid/associations/document_relation/builders.rb +31 -0
  32. data/lib/active_mongoid/associations/document_relation/dependent.rb +26 -0
  33. data/lib/active_mongoid/associations/document_relation/macros.rb +51 -0
  34. data/lib/active_mongoid/associations/document_relation/referenced/in.rb +72 -0
  35. data/lib/active_mongoid/associations/document_relation/referenced/many.rb +125 -0
  36. data/lib/active_mongoid/associations/document_relation/referenced/one.rb +75 -0
  37. data/lib/active_mongoid/associations/many.rb +211 -0
  38. data/lib/active_mongoid/associations/metadata.rb +229 -0
  39. data/lib/active_mongoid/associations/one.rb +21 -0
  40. data/lib/active_mongoid/associations/proxy.rb +38 -0
  41. data/lib/active_mongoid/associations/record_relation/accessors.rb +80 -0
  42. data/lib/active_mongoid/associations/record_relation/associations.rb +33 -0
  43. data/lib/active_mongoid/associations/record_relation/auto_save.rb +43 -0
  44. data/lib/active_mongoid/associations/record_relation/bindings/in.rb +48 -0
  45. data/lib/active_mongoid/associations/record_relation/bindings/many.rb +19 -0
  46. data/lib/active_mongoid/associations/record_relation/bindings/one.rb +19 -0
  47. data/lib/active_mongoid/associations/record_relation/builders.rb +31 -0
  48. data/lib/active_mongoid/associations/record_relation/dependent.rb +26 -0
  49. data/lib/active_mongoid/associations/record_relation/macros.rb +65 -0
  50. data/lib/active_mongoid/associations/record_relation/referenced/in.rb +72 -0
  51. data/lib/active_mongoid/associations/record_relation/referenced/many.rb +128 -0
  52. data/lib/active_mongoid/associations/record_relation/referenced/one.rb +75 -0
  53. data/lib/active_mongoid/associations/targets/enumerable.rb +161 -0
  54. data/lib/active_mongoid/bson_id.rb +44 -0
  55. data/lib/active_mongoid/finder_proxy.rb +55 -0
  56. data/lib/active_mongoid/finders.rb +60 -0
  57. data/lib/active_mongoid/version.rb +3 -0
  58. data/spec/lib/associations/document_relation/accessors_spec.rb +330 -0
  59. data/spec/lib/associations/document_relation/auto_save_spec.rb +157 -0
  60. data/spec/lib/associations/document_relation/bindings/in_spec.rb +39 -0
  61. data/spec/lib/associations/document_relation/bindings/many_spec.rb +36 -0
  62. data/spec/lib/associations/document_relation/bindings/one_spec.rb +39 -0
  63. data/spec/lib/associations/document_relation/builders_spec.rb +117 -0
  64. data/spec/lib/associations/document_relation/dependent_spec.rb +87 -0
  65. data/spec/lib/associations/document_relation/macros_spec.rb +68 -0
  66. data/spec/lib/associations/document_relation/referenced/in_spec.rb +27 -0
  67. data/spec/lib/associations/document_relation/referenced/many_spec.rb +32 -0
  68. data/spec/lib/associations/document_relation/referenced/one_spec.rb +28 -0
  69. data/spec/lib/associations/metadata_spec.rb +157 -0
  70. data/spec/lib/associations/record_relation/accessors_spec.rb +328 -0
  71. data/spec/lib/associations/record_relation/auto_save_spec.rb +157 -0
  72. data/spec/lib/associations/record_relation/bindings/in_spec.rb +39 -0
  73. data/spec/lib/associations/record_relation/bindings/many_spec.rb +39 -0
  74. data/spec/lib/associations/record_relation/bindings/one_spec.rb +57 -0
  75. data/spec/lib/associations/record_relation/builders_spec.rb +118 -0
  76. data/spec/lib/associations/record_relation/dependent_spec.rb +87 -0
  77. data/spec/lib/associations/record_relation/macros_spec.rb +73 -0
  78. data/spec/lib/associations/record_relation/referenced/in_spec.rb +27 -0
  79. data/spec/lib/associations/record_relation/referenced/many_spec.rb +32 -0
  80. data/spec/lib/associations/record_relation/referenced/one_spec.rb +27 -0
  81. data/spec/lib/bson_id_spec.rb +48 -0
  82. data/spec/lib/finders_spec.rb +105 -0
  83. data/spec/spec_helper.rb +89 -0
  84. data/spec/support/models/active_record/address.rb +6 -0
  85. data/spec/support/models/active_record/division.rb +16 -0
  86. data/spec/support/models/active_record/division_setting.rb +9 -0
  87. data/spec/support/models/active_record/player.rb +12 -0
  88. data/spec/support/models/mongoid/league.rb +10 -0
  89. data/spec/support/models/mongoid/person.rb +9 -0
  90. data/spec/support/models/mongoid/post.rb +9 -0
  91. data/spec/support/models/mongoid/stat.rb +8 -0
  92. data/spec/support/models/mongoid/team.rb +9 -0
  93. data/spec/support/shared_examples/shared_many_spec.rb +411 -0
  94. metadata +370 -0
@@ -0,0 +1,33 @@
1
+ require "active_mongoid/associations/document_relation/macros"
2
+ require "active_mongoid/associations/document_relation/accessors"
3
+ require "active_mongoid/associations/document_relation/builders"
4
+ require "active_mongoid/associations/document_relation/auto_save"
5
+ require "active_mongoid/associations/document_relation/dependent"
6
+ require "active_mongoid/associations/document_relation/bindings/one"
7
+ require "active_mongoid/associations/document_relation/bindings/in"
8
+ require "active_mongoid/associations/document_relation/bindings/many"
9
+ require "active_mongoid/associations/document_relation/referenced/one"
10
+ require "active_mongoid/associations/document_relation/referenced/in"
11
+ require "active_mongoid/associations/document_relation/referenced/many"
12
+
13
+ module ActiveMongoid
14
+ module Associations
15
+ module DocumentRelation
16
+ module Associations
17
+ extend ActiveSupport::Concern
18
+
19
+ attr_accessor :__metadata__
20
+
21
+ included do
22
+ include DocumentRelation::Accessors
23
+ include DocumentRelation::Macros
24
+ include DocumentRelation::Builders
25
+ include DocumentRelation::AutoSave
26
+ include DocumentRelation::Dependent
27
+ end
28
+
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,31 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module AutoSave
5
+ extend ActiveSupport::Concern
6
+
7
+ def document_changed_for_autosave?(obj)
8
+ obj.new_record? || obj.changed? || obj.marked_for_destruction?
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ def autosave_documents(metadata)
14
+ if metadata.autosave?
15
+ save_method = :"autosave_documents_for_#{metadata.name}"
16
+ define_method(save_method) do
17
+ if relation = instance_variable_get("@#{metadata.name}")
18
+ Array(relation).each { |d| d.save if document_changed_for_autosave?(d) }
19
+ end
20
+ end
21
+
22
+ after_save save_method
23
+ end
24
+ end
25
+
26
+
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,48 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Bindings
5
+ class In < Associations::Binding
6
+
7
+ def bind_one
8
+ check_inverse!(target)
9
+ bind_foreign_key(base, record_id(target))
10
+ bind_polymorphic_inverse_type(base, target.class.name)
11
+ unless _binding?
12
+ _binding do
13
+ if inverse = __metadata__.inverse(target)
14
+ if set_base_metadata
15
+ if base.referenced_many_records?
16
+ target.__send__(inverse).push(base)
17
+ else
18
+ target.set_record_relation(inverse, base)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def unbind_one
27
+ inverse = __metadata__.inverse(target)
28
+ bind_foreign_key(base, nil)
29
+ bind_polymorphic_inverse_type(base, nil)
30
+ unless _binding?
31
+ _binding do
32
+ if inverse
33
+ set_base_metadata
34
+ if base.referenced_many_records?
35
+ target.__send__(inverse).delete(base)
36
+ else
37
+ target.set_record_relation(inverse, nil)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,19 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Bindings
5
+ class Many < Associations::Binding
6
+
7
+ def bind_one(doc)
8
+ bind_from_relational_parent(doc)
9
+ end
10
+
11
+ def unbind_one(doc)
12
+ unbind_from_relational_parent(doc)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Bindings
5
+ class One < Associations::Binding
6
+
7
+ def bind_one
8
+ bind_from_relational_parent(target)
9
+ end
10
+
11
+ def unbind_one
12
+ unbind_from_relational_parent(target)
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Builders
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def document_builder(name, metadata)
9
+ define_method("build_#{name}") do |attributes = {}|
10
+ record = metadata.klass.new(attributes)
11
+ send("#{name}=", record)
12
+ end
13
+ self
14
+ end
15
+
16
+ def document_creator(name, metadata)
17
+ define_method("create_#{name}") do |attributes = {}|
18
+ record = metadata.klass.new(attributes)
19
+ obj = send("#{name}=", record)
20
+ record.save
21
+ save if metadata.stores_foreign_key?
22
+ obj
23
+ end
24
+ self
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Dependent
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+
9
+ def dependent_documents(metadata)
10
+ if metadata.dependent
11
+ dependent_method = :"dependent_documents_for_#{metadata.name}"
12
+ define_method(dependent_method) do
13
+ relation = get_document_relation(metadata.name, metadata, nil, true)
14
+ Array(relation).each { |d| d.send(metadata.dependent) }
15
+ end
16
+
17
+ before_destroy dependent_method
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Macros
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+
9
+ def belongs_to_document(name, options = {})
10
+ meta = characterize_association(name, Referenced::In, options)
11
+ relate_one_to_one_document(name, meta)
12
+ end
13
+
14
+ def has_one_document(name, options = {})
15
+ meta = characterize_association(name, Referenced::One, options)
16
+ relate_one_to_one_document(name, meta)
17
+ end
18
+
19
+ def has_many_documents(name, options = {})
20
+ meta = characterize_association(name, Referenced::Many, options)
21
+ relate_document(name, meta)
22
+ # document_ids_setter(name, metadata)
23
+ # document_ids_getter(name, metadata)
24
+ end
25
+
26
+ private
27
+
28
+ def relate_one_to_one_document(name, metadata)
29
+ relate_document(name, metadata)
30
+ document_builder(name, metadata)
31
+ document_creator(name, metadata)
32
+ document_id_setter(name, metadata)
33
+ document_id_getter(name, metadata)
34
+ end
35
+
36
+ def relate_document(name, metadata)
37
+ self.am_relations = am_relations.merge(name.to_s => metadata)
38
+ document_getter(name, metadata)
39
+ document_setter(name, metadata)
40
+ autosave_documents(metadata)
41
+ dependent_documents(metadata)
42
+ existence_check(name)
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,72 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Referenced
5
+ class In < Associations::One
6
+
7
+ def initialize(base, target, metadata)
8
+ init(base, target, metadata) do
9
+ bind_one
10
+ end
11
+ end
12
+
13
+ def substitute(replacement)
14
+ unbind_one
15
+ return nil unless replacement
16
+ self.target = normalize(replacement)
17
+ bind_one
18
+ self
19
+ end
20
+
21
+ private
22
+
23
+ def binding
24
+ Bindings::In.new(base, target, __metadata__)
25
+ end
26
+
27
+ def normalize(replacement)
28
+ return replacement if replacement.is_a?(::Mongoid::Document)
29
+ __metadata__.builder(klass, replacement).build
30
+ end
31
+
32
+ class << self
33
+
34
+ def stores_foreign_key?
35
+ true
36
+ end
37
+
38
+ def foreign_key(name)
39
+ "#{name}#{foreign_key_suffix}"
40
+ end
41
+
42
+ def foreign_key_default
43
+ nil
44
+ end
45
+
46
+ def foreign_key_suffix
47
+ "_id"
48
+ end
49
+
50
+ def primary_key_default
51
+ "_id"
52
+ end
53
+
54
+ def macro
55
+ :belongs_to_document
56
+ end
57
+
58
+ def builder(base, meta, object)
59
+ ActiveMongoid::Associations::Builders::In.new(base, meta, object)
60
+ end
61
+
62
+ def criteria(metadata, object, type = nil)
63
+ type.where(metadata.primary_key => object)
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,125 @@
1
+ module ActiveMongoid
2
+ module Associations
3
+ module DocumentRelation
4
+ module Referenced
5
+ class Many < Associations::Many
6
+
7
+ private
8
+
9
+ def criteria
10
+ Many.criteria(__metadata__, base.send(__metadata__.primary_key), base.class)
11
+ end
12
+
13
+ def binding
14
+ Bindings::Many.new(base, target, __metadata__)
15
+ end
16
+
17
+
18
+ def collection
19
+ klass.collection
20
+ end
21
+
22
+ def persist_delayed(docs, inserts)
23
+ unless docs.empty?
24
+ collection.insert(inserts)
25
+ docs.each do |doc|
26
+ doc.new_record = false
27
+ end
28
+ end
29
+ end
30
+
31
+ def save_or_delay(doc, docs, inserts)
32
+ if doc.new_record? && doc.valid?(:create)
33
+ doc.run_callbacks(:save)
34
+ doc.run_callbacks(:create)
35
+ docs.push(doc)
36
+ inserts.push(doc.as_document)
37
+ else
38
+ doc.save
39
+ end
40
+ end
41
+
42
+ def remove_all(conditions = nil, method = :delete_all)
43
+ selector = conditions || {}
44
+ removed = klass.send(method, selector.merge!(criteria.selector))
45
+ target.delete_if do |obj|
46
+ if obj.matches?(selector)
47
+ unbind_one(obj) and true
48
+ end
49
+ end
50
+ removed
51
+ end
52
+
53
+ def remove_not_in(ids)
54
+ removed = criteria.not_in(_id: ids)
55
+ if __metadata__.destructive?
56
+ removed.delete_all
57
+ else
58
+ removed.update_all(__metadata__.foreign_key => nil)
59
+ end
60
+ in_memory.each do |obj|
61
+ if !ids.include?(obj.id)
62
+ unbind_one(obj)
63
+ target.delete(obj)
64
+ if __metadata__.destructive?
65
+ obj.destroyed = true
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ def method_missing(name, *args, &block)
72
+ if target.respond_to?(name)
73
+ target.send(name, *args, &block)
74
+ else
75
+ klass.send(:with_scope, criteria) do
76
+ criteria.public_send(name, *args, &block)
77
+ end
78
+ end
79
+ end
80
+
81
+ class << self
82
+
83
+ def stores_foreign_key?
84
+ false
85
+ end
86
+
87
+ def foreign_key(name)
88
+ "#{name}#{foreign_key_suffix}"
89
+ end
90
+
91
+ def foreign_key_default
92
+ nil
93
+ end
94
+
95
+ def foreign_key_suffix
96
+ "_id"
97
+ end
98
+
99
+ def primary_key_default
100
+ "id"
101
+ end
102
+
103
+ def macro
104
+ :has_many_documents
105
+ end
106
+
107
+ def builder(base, meta, object)
108
+ ActiveMongoid::Associations::Builders::Many.new(base, meta, object || [])
109
+ end
110
+
111
+ def criteria(metadata, object, type = nil)
112
+ crit = metadata.klass.where(metadata.foreign_key => object)
113
+ if metadata.polymorphic?
114
+ crit = crit.where(metadata.type => type.name)
115
+ end
116
+ crit
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end