active_mongoid 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +22 -0
- data/.ruby_gemset +1 -0
- data/.ruby_version +1 -0
- data/.travis.yml +11 -0
- data/Appraisals +7 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +198 -0
- data/Rakefile +7 -0
- data/active_mongoid.gemspec +36 -0
- data/gemfiles/mongoid_2.8.gemfile +7 -0
- data/gemfiles/mongoid_2.8.gemfile.lock +105 -0
- data/gemfiles/mongoid_3.1.gemfile +7 -0
- data/gemfiles/mongoid_3.1.gemfile.lock +108 -0
- data/lib/active_mongoid.rb +8 -0
- data/lib/active_mongoid/associations.rb +82 -0
- data/lib/active_mongoid/associations/binding.rb +77 -0
- data/lib/active_mongoid/associations/builder.rb +26 -0
- data/lib/active_mongoid/associations/builders/in.rb +17 -0
- data/lib/active_mongoid/associations/builders/many.rb +15 -0
- data/lib/active_mongoid/associations/builders/one.rb +15 -0
- data/lib/active_mongoid/associations/document_relation/accessors.rb +100 -0
- data/lib/active_mongoid/associations/document_relation/associations.rb +33 -0
- data/lib/active_mongoid/associations/document_relation/auto_save.rb +31 -0
- data/lib/active_mongoid/associations/document_relation/bindings/in.rb +48 -0
- data/lib/active_mongoid/associations/document_relation/bindings/many.rb +19 -0
- data/lib/active_mongoid/associations/document_relation/bindings/one.rb +19 -0
- data/lib/active_mongoid/associations/document_relation/builders.rb +31 -0
- data/lib/active_mongoid/associations/document_relation/dependent.rb +26 -0
- data/lib/active_mongoid/associations/document_relation/macros.rb +51 -0
- data/lib/active_mongoid/associations/document_relation/referenced/in.rb +72 -0
- data/lib/active_mongoid/associations/document_relation/referenced/many.rb +125 -0
- data/lib/active_mongoid/associations/document_relation/referenced/one.rb +75 -0
- data/lib/active_mongoid/associations/many.rb +211 -0
- data/lib/active_mongoid/associations/metadata.rb +229 -0
- data/lib/active_mongoid/associations/one.rb +21 -0
- data/lib/active_mongoid/associations/proxy.rb +38 -0
- data/lib/active_mongoid/associations/record_relation/accessors.rb +80 -0
- data/lib/active_mongoid/associations/record_relation/associations.rb +33 -0
- data/lib/active_mongoid/associations/record_relation/auto_save.rb +43 -0
- data/lib/active_mongoid/associations/record_relation/bindings/in.rb +48 -0
- data/lib/active_mongoid/associations/record_relation/bindings/many.rb +19 -0
- data/lib/active_mongoid/associations/record_relation/bindings/one.rb +19 -0
- data/lib/active_mongoid/associations/record_relation/builders.rb +31 -0
- data/lib/active_mongoid/associations/record_relation/dependent.rb +26 -0
- data/lib/active_mongoid/associations/record_relation/macros.rb +65 -0
- data/lib/active_mongoid/associations/record_relation/referenced/in.rb +72 -0
- data/lib/active_mongoid/associations/record_relation/referenced/many.rb +128 -0
- data/lib/active_mongoid/associations/record_relation/referenced/one.rb +75 -0
- data/lib/active_mongoid/associations/targets/enumerable.rb +161 -0
- data/lib/active_mongoid/bson_id.rb +44 -0
- data/lib/active_mongoid/finder_proxy.rb +55 -0
- data/lib/active_mongoid/finders.rb +60 -0
- data/lib/active_mongoid/version.rb +3 -0
- data/spec/lib/associations/document_relation/accessors_spec.rb +330 -0
- data/spec/lib/associations/document_relation/auto_save_spec.rb +157 -0
- data/spec/lib/associations/document_relation/bindings/in_spec.rb +39 -0
- data/spec/lib/associations/document_relation/bindings/many_spec.rb +36 -0
- data/spec/lib/associations/document_relation/bindings/one_spec.rb +39 -0
- data/spec/lib/associations/document_relation/builders_spec.rb +117 -0
- data/spec/lib/associations/document_relation/dependent_spec.rb +87 -0
- data/spec/lib/associations/document_relation/macros_spec.rb +68 -0
- data/spec/lib/associations/document_relation/referenced/in_spec.rb +27 -0
- data/spec/lib/associations/document_relation/referenced/many_spec.rb +32 -0
- data/spec/lib/associations/document_relation/referenced/one_spec.rb +28 -0
- data/spec/lib/associations/metadata_spec.rb +157 -0
- data/spec/lib/associations/record_relation/accessors_spec.rb +328 -0
- data/spec/lib/associations/record_relation/auto_save_spec.rb +157 -0
- data/spec/lib/associations/record_relation/bindings/in_spec.rb +39 -0
- data/spec/lib/associations/record_relation/bindings/many_spec.rb +39 -0
- data/spec/lib/associations/record_relation/bindings/one_spec.rb +57 -0
- data/spec/lib/associations/record_relation/builders_spec.rb +118 -0
- data/spec/lib/associations/record_relation/dependent_spec.rb +87 -0
- data/spec/lib/associations/record_relation/macros_spec.rb +73 -0
- data/spec/lib/associations/record_relation/referenced/in_spec.rb +27 -0
- data/spec/lib/associations/record_relation/referenced/many_spec.rb +32 -0
- data/spec/lib/associations/record_relation/referenced/one_spec.rb +27 -0
- data/spec/lib/bson_id_spec.rb +48 -0
- data/spec/lib/finders_spec.rb +105 -0
- data/spec/spec_helper.rb +89 -0
- data/spec/support/models/active_record/address.rb +6 -0
- data/spec/support/models/active_record/division.rb +16 -0
- data/spec/support/models/active_record/division_setting.rb +9 -0
- data/spec/support/models/active_record/player.rb +12 -0
- data/spec/support/models/mongoid/league.rb +10 -0
- data/spec/support/models/mongoid/person.rb +9 -0
- data/spec/support/models/mongoid/post.rb +9 -0
- data/spec/support/models/mongoid/stat.rb +8 -0
- data/spec/support/models/mongoid/team.rb +9 -0
- data/spec/support/shared_examples/shared_many_spec.rb +411 -0
- 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
|