djsun-mongomapper 0.3.1.1 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History +20 -1
- data/Rakefile +5 -3
- data/VERSION +1 -1
- data/lib/mongomapper/associations/base.rb +3 -5
- data/lib/mongomapper/associations/belongs_to_polymorphic_proxy.rb +5 -3
- data/lib/mongomapper/associations/belongs_to_proxy.rb +4 -4
- data/lib/mongomapper/associations/many_documents_proxy.rb +32 -14
- data/lib/mongomapper/associations/proxy.rb +2 -6
- data/lib/mongomapper/associations.rb +38 -15
- data/lib/mongomapper/document.rb +165 -95
- data/lib/mongomapper/dynamic_finder.rb +38 -0
- data/lib/mongomapper/embedded_document.rb +116 -88
- data/lib/mongomapper/finder_options.rb +3 -14
- data/lib/mongomapper/key.rb +12 -16
- data/lib/mongomapper/serializers/json_serializer.rb +15 -12
- data/lib/mongomapper/support.rb +30 -0
- data/lib/mongomapper.rb +7 -33
- data/mongomapper.gemspec +10 -7
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +14 -0
- data/test/functional/associations/test_belongs_to_proxy.rb +10 -0
- data/test/functional/associations/test_many_polymorphic_proxy.rb +46 -52
- data/test/functional/associations/test_many_proxy.rb +71 -12
- data/test/functional/test_associations.rb +9 -2
- data/test/functional/test_document.rb +281 -20
- data/test/functional/test_rails_compatibility.rb +2 -3
- data/test/models.rb +39 -8
- data/test/unit/serializers/test_json_serializer.rb +46 -12
- data/test/unit/test_association_base.rb +10 -2
- data/test/unit/test_document.rb +7 -9
- data/test/unit/test_embedded_document.rb +180 -24
- data/test/unit/test_finder_options.rb +7 -38
- data/test/unit/test_key.rb +54 -24
- metadata +5 -5
- data/test/unit/test_mongo_id.rb +0 -35
data/History
CHANGED
@@ -1,8 +1,27 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.4 (master)
|
2
|
+
* BACKWORDS COMPATIBILITY BREAK: Timestamps are now optional. To use them add timestamps! to your model.
|
3
|
+
* BACKWORDS COMPATIBILITY BREAK: Associations keys are no longer created automatically when you use belongs_to and many. Too much was hidden from the developer. You now have to declare them like key :creator_id, String and such.
|
4
|
+
|
5
|
+
0.3.3 8/16/2009
|
6
|
+
* BACKWORDS COMPATIBILITY BREAK: _id is now once again a string rather than an object id and will stay that way.
|
7
|
+
* Custom id's can now be used because of the change to string id's
|
8
|
+
* Added dynamic finders to document. (dcu)
|
9
|
+
* Added destroy_all, delete_all and nullify for many document association
|
10
|
+
* Added :dependent option for many documents assocation (dcu)
|
11
|
+
* update_attributes now returns true or false instead of the document. (Durran Jordan and me)
|
12
|
+
* Keys no longer require a type
|
13
|
+
* Keys can now be added on the fly using []=
|
14
|
+
|
15
|
+
0.3.2 8/6/2009
|
2
16
|
* Added many polymorphic documents association
|
3
17
|
* Implemented build and create for many and many polymorphic documents
|
4
18
|
* <<, push and concat now work correctly for many and many polymorphic documents
|
5
19
|
* find(:first) now accepts order option
|
20
|
+
* id is now included by default with to_json
|
21
|
+
* _id is now always excluded from to_json
|
22
|
+
* Times are now always returned as UTC
|
23
|
+
* Default values are now a bit more intelligent for Array and Hash keys (djsun)
|
24
|
+
* Embedded documents now have _id as well so they can be identified more easily
|
6
25
|
|
7
26
|
0.3.1 7/28/2009
|
8
27
|
* 1 minor tweak
|
data/Rakefile
CHANGED
@@ -12,14 +12,16 @@ begin
|
|
12
12
|
gem.rubyforge_project = "mongomapper"
|
13
13
|
|
14
14
|
gem.add_dependency('activesupport')
|
15
|
-
gem.add_dependency('mongodb-mongo', '0.
|
15
|
+
gem.add_dependency('mongodb-mongo', '0.11.1')
|
16
16
|
gem.add_dependency('jnunemaker-validatable', '1.7.2')
|
17
17
|
|
18
18
|
gem.add_development_dependency('mocha', '0.9.4')
|
19
19
|
gem.add_development_dependency('jnunemaker-matchy', '0.4.0')
|
20
20
|
end
|
21
|
-
|
22
|
-
Jeweler::RubyforgeTasks.new
|
21
|
+
|
22
|
+
Jeweler::RubyforgeTasks.new do |rubyforge|
|
23
|
+
rubyforge.doc_task = "rdoc"
|
24
|
+
end
|
23
25
|
rescue LoadError
|
24
26
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
25
27
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.3
|
@@ -4,9 +4,7 @@ module MongoMapper
|
|
4
4
|
attr_reader :type, :name, :options
|
5
5
|
|
6
6
|
def initialize(type, name, options = {})
|
7
|
-
@options = options
|
8
|
-
@type = type
|
9
|
-
@name = name
|
7
|
+
@type, @name, @options = type, name, options
|
10
8
|
end
|
11
9
|
|
12
10
|
def class_name
|
@@ -41,8 +39,8 @@ module MongoMapper
|
|
41
39
|
@type_key_name ||= many? ? '_type' : "#{name}_type"
|
42
40
|
end
|
43
41
|
|
44
|
-
def
|
45
|
-
"#{name}_id"
|
42
|
+
def foreign_key
|
43
|
+
@options[:foreign_key] || "#{name}_id"
|
46
44
|
end
|
47
45
|
|
48
46
|
def ivar
|
@@ -7,18 +7,20 @@ module MongoMapper
|
|
7
7
|
id, type = doc.id, doc.class.name
|
8
8
|
end
|
9
9
|
|
10
|
-
@owner.send("#{@association.
|
10
|
+
@owner.send("#{@association.foreign_key}=", id)
|
11
11
|
@owner.send("#{@association.type_key_name}=", type)
|
12
12
|
reset
|
13
13
|
end
|
14
14
|
|
15
15
|
protected
|
16
16
|
def find_target
|
17
|
-
|
17
|
+
if proxy_id && proxy_class
|
18
|
+
proxy_class.find_by_id(proxy_id)
|
19
|
+
end
|
18
20
|
end
|
19
21
|
|
20
22
|
def proxy_id
|
21
|
-
@proxy_id ||= @owner.send(@association.
|
23
|
+
@proxy_id ||= @owner.send(@association.foreign_key)
|
22
24
|
end
|
23
25
|
|
24
26
|
def proxy_class
|
@@ -7,14 +7,14 @@ module MongoMapper
|
|
7
7
|
id = doc.id
|
8
8
|
end
|
9
9
|
|
10
|
-
@owner.send("#{@association.
|
10
|
+
@owner.send("#{@association.foreign_key}=", id)
|
11
11
|
reset
|
12
12
|
end
|
13
13
|
|
14
|
-
protected
|
14
|
+
protected
|
15
15
|
def find_target
|
16
|
-
if association_id = @owner.send(@association.
|
17
|
-
@association.klass.
|
16
|
+
if association_id = @owner.send(@association.foreign_key)
|
17
|
+
@association.klass.find_by_id(association_id)
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
@@ -2,38 +2,38 @@ module MongoMapper
|
|
2
2
|
module Associations
|
3
3
|
class ManyDocumentsProxy < Proxy
|
4
4
|
delegate :klass, :to => :@association
|
5
|
-
|
5
|
+
|
6
6
|
def find(*args)
|
7
7
|
options = args.extract_options!
|
8
8
|
klass.find(*args << scoped_options(options))
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
def paginate(options)
|
12
12
|
klass.paginate(scoped_options(options))
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def all(options={})
|
16
16
|
find(:all, scoped_options(options))
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def first(options={})
|
20
20
|
find(:first, scoped_options(options))
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def last(options={})
|
24
24
|
find(:last, scoped_options(options))
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def count(conditions={})
|
28
28
|
klass.count(conditions.deep_merge(scoped_conditions))
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def replace(docs)
|
32
32
|
@target.map(&:destroy) if load_target
|
33
33
|
docs.each { |doc| apply_scope(doc).save }
|
34
34
|
reset
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def <<(*docs)
|
38
38
|
ensure_owner_saved
|
39
39
|
flatten_deeper(docs).each { |doc| apply_scope(doc).save }
|
@@ -41,36 +41,54 @@ module MongoMapper
|
|
41
41
|
end
|
42
42
|
alias_method :push, :<<
|
43
43
|
alias_method :concat, :<<
|
44
|
-
|
44
|
+
|
45
45
|
def build(attrs={})
|
46
46
|
doc = klass.new(attrs)
|
47
47
|
apply_scope(doc)
|
48
48
|
doc
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
def create(attrs={})
|
52
52
|
doc = klass.new(attrs)
|
53
53
|
apply_scope(doc).save
|
54
54
|
doc
|
55
55
|
end
|
56
|
+
|
57
|
+
def destroy_all(conditions={})
|
58
|
+
all(:conditions => conditions).map(&:destroy)
|
59
|
+
reset
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete_all(conditions={})
|
63
|
+
klass.delete_all(conditions.deep_merge(scoped_conditions))
|
64
|
+
reset
|
65
|
+
end
|
56
66
|
|
67
|
+
def nullify
|
68
|
+
criteria = FinderOptions.to_mongo_criteria(scoped_conditions)
|
69
|
+
all(criteria).each do |doc|
|
70
|
+
doc.update_attributes self.foreign_key => nil
|
71
|
+
end
|
72
|
+
reset
|
73
|
+
end
|
74
|
+
|
57
75
|
protected
|
58
76
|
def scoped_conditions
|
59
77
|
{self.foreign_key => @owner.id}
|
60
78
|
end
|
61
|
-
|
79
|
+
|
62
80
|
def scoped_options(options)
|
63
81
|
options.deep_merge({:conditions => scoped_conditions})
|
64
82
|
end
|
65
|
-
|
83
|
+
|
66
84
|
def find_target
|
67
85
|
find(:all)
|
68
86
|
end
|
69
|
-
|
87
|
+
|
70
88
|
def ensure_owner_saved
|
71
89
|
@owner.save if @owner.new?
|
72
90
|
end
|
73
|
-
|
91
|
+
|
74
92
|
def apply_scope(doc)
|
75
93
|
ensure_owner_saved
|
76
94
|
doc.send("#{self.foreign_key}=", @owner.id)
|
@@ -1,12 +1,8 @@
|
|
1
1
|
module MongoMapper
|
2
2
|
module Associations
|
3
|
-
class Proxy
|
3
|
+
class Proxy < BasicObject
|
4
4
|
attr_reader :owner, :association
|
5
|
-
|
6
|
-
instance_methods.each do |m|
|
7
|
-
undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/
|
8
|
-
end
|
9
|
-
|
5
|
+
|
10
6
|
def initialize(owner, association)
|
11
7
|
@owner = owner
|
12
8
|
@association = association
|
@@ -2,12 +2,12 @@ module MongoMapper
|
|
2
2
|
module Associations
|
3
3
|
module ClassMethods
|
4
4
|
def belongs_to(association_id, options = {})
|
5
|
-
create_association(:belongs_to, association_id, options)
|
5
|
+
create_association(:belongs_to, association_id, options)
|
6
6
|
self
|
7
7
|
end
|
8
8
|
|
9
9
|
def many(association_id, options = {})
|
10
|
-
create_association(:many, association_id, options)
|
10
|
+
create_association(:many, association_id, options)
|
11
11
|
self
|
12
12
|
end
|
13
13
|
|
@@ -20,29 +20,52 @@ module MongoMapper
|
|
20
20
|
association = Associations::Base.new(type, name, options)
|
21
21
|
associations[association.name] = association
|
22
22
|
define_association_methods(association)
|
23
|
-
|
23
|
+
define_dependent_callback(association)
|
24
24
|
association
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def define_association_methods(association)
|
28
28
|
define_method(association.name) do
|
29
29
|
get_proxy(association)
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
define_method("#{association.name}=") do |value|
|
33
33
|
get_proxy(association).replace(value)
|
34
34
|
value
|
35
35
|
end
|
36
36
|
end
|
37
|
-
|
38
|
-
def
|
39
|
-
if association.
|
40
|
-
|
41
|
-
|
37
|
+
|
38
|
+
def define_dependent_callback(association)
|
39
|
+
if association.options[:dependent]
|
40
|
+
if association.many?
|
41
|
+
define_dependent_callback_for_many(association)
|
42
|
+
elsif association.belongs_to?
|
43
|
+
define_dependent_callback_for_belongs_to(association)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def define_dependent_callback_for_many(association)
|
49
|
+
return if association.embeddable?
|
50
|
+
|
51
|
+
after_destroy do |doc|
|
52
|
+
case association.options[:dependent]
|
53
|
+
when :destroy
|
54
|
+
doc.get_proxy(association).destroy_all
|
55
|
+
when :delete_all
|
56
|
+
doc.get_proxy(association).delete_all
|
57
|
+
when :nullify
|
58
|
+
doc.get_proxy(association).nullify
|
59
|
+
end
|
42
60
|
end
|
43
|
-
|
44
|
-
|
45
|
-
|
61
|
+
end
|
62
|
+
|
63
|
+
def define_dependent_callback_for_belongs_to(association)
|
64
|
+
after_destroy do |doc|
|
65
|
+
case association.options[:dependent]
|
66
|
+
when :destroy
|
67
|
+
doc.get_proxy(association).destroy
|
68
|
+
end
|
46
69
|
end
|
47
70
|
end
|
48
71
|
end
|
@@ -51,9 +74,9 @@ module MongoMapper
|
|
51
74
|
def get_proxy(association)
|
52
75
|
unless proxy = self.instance_variable_get(association.ivar)
|
53
76
|
proxy = association.proxy_class.new(self, association)
|
54
|
-
self.instance_variable_set(association.ivar, proxy)
|
77
|
+
self.instance_variable_set(association.ivar, proxy) if !frozen?
|
55
78
|
end
|
56
|
-
|
79
|
+
|
57
80
|
proxy
|
58
81
|
end
|
59
82
|
end
|