mm_no_empties 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
data/lib/mm_no_empties.rb
CHANGED
@@ -2,11 +2,48 @@ require 'mongo_mapper'
|
|
2
2
|
require "mm_no_empties/version"
|
3
3
|
require 'mongo_mapper/plugins/keys/key'
|
4
4
|
|
5
|
+
#modified versions of to_mongo that check nested values
|
6
|
+
require_relative 'mongo_mapper/extensions/array'
|
7
|
+
require_relative 'mongo_mapper/extensions/hash'
|
8
|
+
require_relative 'mongo_mapper/extensions/set'
|
9
|
+
|
5
10
|
module MmNoEmpties
|
6
11
|
|
7
12
|
extend ActiveSupport::Concern
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
|
16
|
+
def set(*args)
|
17
|
+
criteria, updates, options = criteria_and_keys_from_args(args)
|
18
|
+
|
19
|
+
unset_cmd = {}
|
20
|
+
|
21
|
+
updates.each do |key, value|
|
22
|
+
updates[key] = keys[key.to_s].set(value) if key?(key)
|
23
|
+
unset_cmd[key] = 1 unless updates[key].present?
|
24
|
+
end
|
25
|
+
|
26
|
+
set_attr = updates.except(*unset_cmd.keys)
|
27
|
+
|
28
|
+
update_cmd = {}
|
29
|
+
update_cmd['$set'] = set_attr if set_attr.present?
|
30
|
+
update_cmd['$unset'] = unset_cmd if unset_cmd.present?
|
31
|
+
|
32
|
+
if options
|
33
|
+
collection.update(criteria, update_cmd, options.merge(:multi => true))
|
34
|
+
else
|
35
|
+
collection.update(criteria, update_cmd, :multi => true)
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
8
41
|
|
9
|
-
def attributes(
|
42
|
+
def attributes(options = {})
|
43
|
+
|
44
|
+
include_all = options[:include_all]
|
45
|
+
stringify_bson = options[:stringify_bson]
|
46
|
+
recursive = options[:recursive]
|
10
47
|
|
11
48
|
HashWithIndifferentAccess.new.tap do |attrs|
|
12
49
|
persistable_keys = if include_all
|
@@ -20,17 +57,23 @@ module MmNoEmpties
|
|
20
57
|
end
|
21
58
|
|
22
59
|
persistable_keys.each do |name, key|
|
23
|
-
|
24
|
-
|
60
|
+
v = key.set(self[key.name])
|
61
|
+
case v
|
62
|
+
when MongoMapper::Document, MongoMapper::EmbeddedDocument, Hash, Array, Set
|
63
|
+
v = v.to_mongo(options) if v and recursive
|
64
|
+
when BSON::ObjectId, BSON::Binary
|
65
|
+
v = v.to_s if stringify_bson
|
66
|
+
end
|
67
|
+
attrs[name] = v
|
25
68
|
end
|
26
69
|
|
27
70
|
embedded_associations.each do |association|
|
28
71
|
if documents = instance_variable_get(association.ivar)
|
29
72
|
|
30
73
|
val = if association.is_a?(MongoMapper::Plugins::Associations::OneAssociation)
|
31
|
-
documents.to_mongo
|
74
|
+
documents.to_mongo(options)
|
32
75
|
else
|
33
|
-
documents.map { |document| document.to_mongo }
|
76
|
+
documents.map { |document| document.to_mongo(options) }
|
34
77
|
end
|
35
78
|
|
36
79
|
if include_all
|
@@ -45,5 +88,6 @@ module MmNoEmpties
|
|
45
88
|
end
|
46
89
|
alias :to_mongo :attributes
|
47
90
|
|
48
|
-
|
49
91
|
end
|
92
|
+
|
93
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module MongoMapper
|
3
|
+
module Extensions
|
4
|
+
module Array
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def to_mongo(value, options = {})
|
11
|
+
stringify_bson = options[:stringify_bson]
|
12
|
+
recursive = options[:recursive]
|
13
|
+
|
14
|
+
value = value.clone if recursive
|
15
|
+
value = value.respond_to?(:lines) ? value.lines : value
|
16
|
+
value = value.to_a
|
17
|
+
value.map! do |v|
|
18
|
+
|
19
|
+
case v
|
20
|
+
when Document, EmbeddedDocument, Hash, Array, Set
|
21
|
+
v = v.to_mongo(options) if v and recursive
|
22
|
+
when BSON::ObjectId, BSON::Binary
|
23
|
+
v = v.to_s if stringify_bson
|
24
|
+
end
|
25
|
+
|
26
|
+
v
|
27
|
+
|
28
|
+
end
|
29
|
+
value
|
30
|
+
end
|
31
|
+
|
32
|
+
def from_mongo(value)
|
33
|
+
value || []
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_mongo(options = {})
|
39
|
+
self.class.to_mongo(self, options)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class Array
|
47
|
+
include MongoMapper::Extensions::Array
|
48
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module MongoMapper
|
3
|
+
module Extensions
|
4
|
+
module Hash
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def to_mongo(value, options = {})
|
11
|
+
stringify_bson = options[:stringify_bson]
|
12
|
+
recursive = options[:recursive]
|
13
|
+
|
14
|
+
value = value.clone if recursive
|
15
|
+
hash = value.to_hash
|
16
|
+
hash.each do |k,v|
|
17
|
+
|
18
|
+
case v
|
19
|
+
when Document, EmbeddedDocument, Hash, Array, Set
|
20
|
+
v = v.to_mongo(options) if v and recursive
|
21
|
+
when BSON::ObjectId, BSON::Binary
|
22
|
+
v = v.to_s if stringify_bson
|
23
|
+
end
|
24
|
+
|
25
|
+
hash[k] = v
|
26
|
+
|
27
|
+
end
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
|
31
|
+
def from_mongo(value)
|
32
|
+
HashWithIndifferentAccess.new(value || {})
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_mongo(options = {})
|
38
|
+
self.class.to_mongo(self, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Hash
|
46
|
+
include MongoMapper::Extensions::Hash
|
47
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
module MongoMapper
|
5
|
+
module Extensions
|
6
|
+
module Set
|
7
|
+
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def to_mongo(value, options = {})
|
13
|
+
recursive = options[:recursive]
|
14
|
+
v = value.to_a
|
15
|
+
v = v.to_mongo(options) if recursive
|
16
|
+
v
|
17
|
+
end
|
18
|
+
|
19
|
+
def from_mongo(value)
|
20
|
+
(value || []).to_set
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_mongo(options = {})
|
26
|
+
self.class.to_mongo(self, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class Set
|
34
|
+
include MongoMapper::Extensions::Set
|
35
|
+
end
|
data/spec/mm_no_empties_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require File.expand_path('../../lib/mm_no_empties', __FILE__)
|
2
|
+
require 'pry'
|
2
3
|
|
3
4
|
describe MmNoEmpties do
|
4
5
|
|
@@ -36,8 +37,9 @@ describe MmNoEmpties do
|
|
36
37
|
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
|
37
38
|
MongoMapper.database = 'mm_no_empties_test'
|
38
39
|
|
39
|
-
@group = Group.create
|
40
40
|
@person = Person.new(name: 'Jon', age: 33)
|
41
|
+
@group = Group.create :people => [@person]
|
42
|
+
|
41
43
|
end
|
42
44
|
|
43
45
|
it "should not include empty Arrays, Hashes and Sets in 'attributes'" do
|
@@ -49,11 +51,44 @@ describe MmNoEmpties do
|
|
49
51
|
end
|
50
52
|
|
51
53
|
it "should not include unused many associations in attributes" do
|
52
|
-
@group.attributes.keys.should_not include('
|
54
|
+
@group.attributes.keys.should_not include('owner', 'company_id')
|
53
55
|
end
|
54
56
|
|
55
57
|
it "should restore empty fields when loading from the database" do
|
56
|
-
Group.first.attributes(:include_all).keys.should include('names', 'counts', 'tags')
|
58
|
+
Group.first.attributes(:include_all => true).keys.should include('names', 'counts', 'tags')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should call to_mongo on array elements when recursive is true" do
|
62
|
+
@group['an_array'] = [1, 2, [3, 4].to_set]
|
63
|
+
@group.attributes(:recursive => true)['an_array'].should == [1, 2, [3, 4]]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should call to_mongo on set elements when recursive is true" do
|
67
|
+
@group['a_set'] = [1, 2, [3, 4].to_set].to_set
|
68
|
+
@group.attributes(:recursive => true)['a_set'].should == [1, 2, [3, 4]]
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should call to_mongo on hash values when recursive is true" do
|
72
|
+
@group['a_hash'] = {:a => [1, 2].to_set}
|
73
|
+
@group.attributes(:recursive => true)['a_hash']['a'].should == [1, 2]
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should convert a BSON::ObjectId to a string if stringify_bson is true" do
|
77
|
+
@group.attributes(:stringify_bson => true)['_id'].should == @group.id.to_s
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should convert a BSON::ObjectId in an embedded document to a string if stringify_bson is true" do
|
81
|
+
@group.attributes(:stringify_bson => true)['people'].first['_id'].should == @person.id.to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should convert a BSON::Binary to a string if stringify_bson is true" do
|
85
|
+
@group['a_bson_binary'] = BSON::Binary.new("foo")
|
86
|
+
@group.attributes(:stringify_bson => true)['a_bson_binary'].should be_an_instance_of String
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should convert a BSON::Binary in an embedded document to a string if stringify_bson is true" do
|
90
|
+
@group.people.first['a_bson_binary'] = BSON::Binary.new("foo")
|
91
|
+
@group.attributes(:stringify_bson => true)['people'].first['a_bson_binary'].should be_an_instance_of String
|
57
92
|
end
|
58
93
|
|
59
94
|
after(:all) do
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 5
|
9
|
+
version: 0.0.5
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jonathan Chambers
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2012-
|
17
|
+
date: 2012-12-21 00:00:00 +00:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -78,6 +78,9 @@ files:
|
|
78
78
|
- Rakefile
|
79
79
|
- lib/mm_no_empties.rb
|
80
80
|
- lib/mm_no_empties/version.rb
|
81
|
+
- lib/mongo_mapper/extensions/array.rb
|
82
|
+
- lib/mongo_mapper/extensions/hash.rb
|
83
|
+
- lib/mongo_mapper/extensions/set.rb
|
81
84
|
- mm_no_empties.gemspec
|
82
85
|
- spec/mm_no_empties_spec.rb
|
83
86
|
has_rdoc: true
|