mongo_persist 0.0.1 → 0.0.2
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/README.rdoc +43 -33
- data/VERSION +1 -1
- data/lib/mongo_persist/sandbox.rb +41 -0
- data/lib/mongo_persist.rb +30 -12
- data/mongo_persist.gemspec +61 -0
- data/spec/mongo_persist_spec.rb +30 -6
- metadata +3 -1
data/README.rdoc
CHANGED
@@ -1,50 +1,60 @@
|
|
1
|
-
=
|
1
|
+
= MongoPersist
|
2
2
|
|
3
3
|
Library to add MongoDB Persistance to normal Ruby objects
|
4
4
|
|
5
5
|
= Example
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
require 'rubygems'
|
8
|
+
require 'mongo'
|
9
|
+
require 'mongo_persist'
|
10
|
+
|
11
|
+
class Order
|
12
|
+
include MongoPersist
|
13
|
+
attr_accessor :po_number
|
14
|
+
fattr(:order_products) { [] }
|
15
|
+
def products
|
16
|
+
order_products.map { |x| x.product }
|
17
|
+
end
|
13
18
|
end
|
14
|
-
end
|
15
19
|
|
16
|
-
class OrderProduct
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
class OrderProduct
|
21
|
+
include MongoPersist
|
22
|
+
attr_accessor :unit_price, :quantity, :product
|
23
|
+
|
24
|
+
# Store a reference to objects for this attribute, not the entire object.
|
25
|
+
mongo_reference_attributes ['product']
|
26
|
+
end
|
21
27
|
|
22
|
-
class Product
|
23
|
-
|
24
|
-
|
25
|
-
end
|
28
|
+
class Product
|
29
|
+
include MongoPersist
|
30
|
+
attr_accessor :name
|
31
|
+
end
|
26
32
|
|
27
|
-
products = [Product.new(:name => 'Leather Couch'),Product.new(:name => 'Maroon Chair')].each { |x| x.mongo_save! }
|
33
|
+
products = [Product.new(:name => 'Leather Couch'),Product.new(:name => 'Maroon Chair')].each { |x| x.mongo_save! }
|
28
34
|
|
29
|
-
orders = []
|
30
|
-
orders << Order.new(:po_number => 1234, :order_products => [OrderProduct.new(:unit_price => 1000, :quantity => 1, :product => products[0])]).mongo_save!
|
31
|
-
orders << Order.new(:po_number => 1235, :order_products => [OrderProduct.new(:unit_price => 200, :quantity => 2, :product => products[1])]).mongo_save!
|
35
|
+
orders = []
|
36
|
+
orders << Order.new(:po_number => 1234, :order_products => [OrderProduct.new(:unit_price => 1000, :quantity => 1, :product => products[0])]).mongo_save!
|
37
|
+
orders << Order.new(:po_number => 1235, :order_products => [OrderProduct.new(:unit_price => 200, :quantity => 2, :product => products[1])]).mongo_save!
|
32
38
|
|
33
|
-
# objects are saved to MongoDB as JSON objects
|
39
|
+
# objects are saved to MongoDB as JSON objects
|
34
40
|
|
35
|
-
# get all order objects back from Mongo
|
36
|
-
# you get back the ruby objects you put in, not raw JSON objects
|
37
|
-
Order.collection.find_objects
|
41
|
+
# get all order objects back from Mongo
|
42
|
+
# you get back the ruby objects you put in, not raw JSON objects
|
43
|
+
Order.collection.find_objects
|
38
44
|
|
39
|
-
# Since on OrderProduct, the product attribute was marked as a reference attribute,
|
40
|
-
#
|
41
|
-
|
42
|
-
|
45
|
+
# Since on OrderProduct, the product attribute was marked as a reference attribute,
|
46
|
+
# the product is stored in MongoDB only as a reference to the product obj
|
47
|
+
#
|
48
|
+
# When you read the Order/OrderProduct back out, MongoPersist takes care of
|
49
|
+
# fetching the Product object again. You don't have to do anything.
|
50
|
+
Order.collection.find_one_object.products.first # An object of class Product
|
51
|
+
Order.collection.find_one_object.products.first.name # Leather Couch
|
43
52
|
|
44
|
-
# Because the product is stored as a reference, if you update that product
|
45
|
-
|
46
|
-
products[0].
|
47
|
-
|
53
|
+
# Because the product is stored as a reference, if you update that product
|
54
|
+
# elsewhere and save to Mongo, later reads of Orders with that product will be correctly updated
|
55
|
+
products[0].name = 'White Leather Couch'
|
56
|
+
products[0].mongo_save!
|
57
|
+
Order.collection.find_one_object.products.first.name # White Leather Couch
|
48
58
|
|
49
59
|
|
50
60
|
== Note on Patches/Pull Requests
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../mongo_persist"
|
2
|
+
|
3
|
+
def db
|
4
|
+
Mongo::Connection.new.db('test-db')
|
5
|
+
end
|
6
|
+
|
7
|
+
class Order
|
8
|
+
include MongoPersist
|
9
|
+
attr_accessor :po_number, :customers
|
10
|
+
mongo_reference_attributes ['customers']
|
11
|
+
fattr(:order_products) { [] }
|
12
|
+
def products
|
13
|
+
order_products.map { |x| x.product }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class OrderProduct
|
18
|
+
include MongoPersist
|
19
|
+
attr_accessor :unit_price, :quantity, :product
|
20
|
+
mongo_reference_attributes ['product']
|
21
|
+
end
|
22
|
+
|
23
|
+
class Product
|
24
|
+
include MongoPersist
|
25
|
+
attr_accessor :name
|
26
|
+
end
|
27
|
+
|
28
|
+
class Customer
|
29
|
+
include MongoPersist
|
30
|
+
attr_accessor :email
|
31
|
+
end
|
32
|
+
|
33
|
+
[Order,Product].each { |x| x.collection.remove }
|
34
|
+
@products = [Product.new(:name => 'Leather Couch'),Product.new(:name => 'Maroon Chair')].each { |x| x.mongo.save! }
|
35
|
+
@customers = [Customer.new(:email => 'a'),Customer.new(:email => 'b')].each { |x| x.mongo.save! }
|
36
|
+
|
37
|
+
@orders = []
|
38
|
+
@orders << Order.new(:customers => @customers, :po_number => 1234, :order_products => [OrderProduct.new(:unit_price => 1000, :quantity => 1, :product => @products[0])]).mongo.save!
|
39
|
+
@orders << Order.new(:customers => @customers, :po_number => 1235, :order_products => [OrderProduct.new(:unit_price => 200, :quantity => 2, :product => @products[1])]).mongo.save!
|
40
|
+
|
41
|
+
$orders = @orders
|
data/lib/mongo_persist.rb
CHANGED
@@ -3,6 +3,7 @@ require 'mongo'
|
|
3
3
|
require 'activesupport'
|
4
4
|
require 'fattr'
|
5
5
|
require File.dirname(__FILE__) + "/mongo_persist/util"
|
6
|
+
require 'andand'
|
6
7
|
|
7
8
|
class Object
|
8
9
|
def safe_to_mongo_hash
|
@@ -20,6 +21,9 @@ class Array
|
|
20
21
|
def to_mongo_object
|
21
22
|
map { |x| x.safe_to_mongo_object }
|
22
23
|
end
|
24
|
+
def to_mongo_ref_hash
|
25
|
+
map { |x| x.to_mongo_ref_hash }
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
class Hash
|
@@ -39,29 +43,50 @@ class Hash
|
|
39
43
|
h.reject { |k,v| k == '_id' }
|
40
44
|
end
|
41
45
|
def to_mongo_object
|
42
|
-
return
|
46
|
+
return map_value { |v| v.safe_to_mongo_object } unless mongo_class
|
43
47
|
if naked_reference?
|
44
48
|
mongo_class.collection.find_one_object('_id' => get_mongo_id)
|
45
49
|
else
|
46
50
|
mongo_class.from_mongo_hash(to_mongo_hash_for_obj)
|
47
51
|
end
|
48
52
|
end
|
53
|
+
def to_mongo_hash
|
54
|
+
res = {}
|
55
|
+
each { |k,v| res[k.safe_to_mongo_hash] = v.safe_to_mongo_hash }
|
56
|
+
res
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class MongoWrapper
|
61
|
+
attr_accessor :obj
|
62
|
+
include FromHash
|
63
|
+
def save!
|
64
|
+
if obj.mongo_id
|
65
|
+
obj.klass.collection.update({'_id' => obj.mongo_id},obj.to_mongo_hash)
|
66
|
+
else
|
67
|
+
obj.mongo_id = obj.class.collection.save(obj.to_mongo_hash)
|
68
|
+
end
|
69
|
+
obj
|
70
|
+
end
|
49
71
|
end
|
50
72
|
|
51
73
|
module MongoPersist
|
52
74
|
attr_accessor :mongo_id
|
53
75
|
#can be overriden by class. If not, assumes that all instance variables should be saved.
|
54
76
|
def mongo_attributes
|
55
|
-
instance_variables.map { |x| x[1..-1] }
|
77
|
+
instance_variables.map { |x| x[1..-1] } - ['mongo']
|
56
78
|
end
|
57
79
|
def mongo_child_attributes
|
58
80
|
mongo_attributes - self.class.mongo_reference_attributes
|
59
81
|
end
|
82
|
+
def to_mongo_ref_hash
|
83
|
+
{'_mongo_class' => klass.to_s, '_id' => mongo_id}
|
84
|
+
end
|
60
85
|
def to_mongo_hash
|
61
86
|
res = mongo_child_attributes.inject({}) { |h,attr| h.merge(attr => send(attr).safe_to_mongo_hash) }.merge("_mongo_class" => self.class.to_s)
|
62
87
|
klass.mongo_reference_attributes.each do |attr|
|
63
|
-
|
64
|
-
res[attr] =
|
88
|
+
val = send(attr)
|
89
|
+
res[attr] = val.to_mongo_ref_hash if val
|
65
90
|
end
|
66
91
|
res
|
67
92
|
end
|
@@ -69,14 +94,7 @@ module MongoPersist
|
|
69
94
|
h = h.map_value { |v| v.safe_to_mongo_object }
|
70
95
|
from_hash(h)
|
71
96
|
end
|
72
|
-
|
73
|
-
if mongo_id
|
74
|
-
klass.collection.update({'_id' => mongo_id},to_mongo_hash)
|
75
|
-
else
|
76
|
-
self.mongo_id = self.class.collection.save(to_mongo_hash)
|
77
|
-
end
|
78
|
-
self
|
79
|
-
end
|
97
|
+
fattr(:mongo) { MongoWrapper.new(:obj => self) }
|
80
98
|
|
81
99
|
module ClassMethods
|
82
100
|
dsl_method(:mongo_reference_attributes) { [] }
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{mongo_persist}
|
8
|
+
s.version = "0.0.2"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Mike Harris"]
|
12
|
+
s.date = %q{2009-11-19}
|
13
|
+
s.description = %q{Library to add MongoDB Persistance to normal Ruby objects}
|
14
|
+
s.email = %q{mharris717@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".gitignore",
|
22
|
+
"LICENSE",
|
23
|
+
"README.rdoc",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"lib/mongo_persist.rb",
|
27
|
+
"lib/mongo_persist/sandbox.rb",
|
28
|
+
"lib/mongo_persist/util.rb",
|
29
|
+
"mongo_persist.gemspec",
|
30
|
+
"spec/mongo_persist_spec.rb",
|
31
|
+
"spec/spec_helper.rb"
|
32
|
+
]
|
33
|
+
s.homepage = %q{http://github.com/mharris717/mongo_persist}
|
34
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
35
|
+
s.require_paths = ["lib"]
|
36
|
+
s.rubygems_version = %q{1.3.5}
|
37
|
+
s.summary = %q{Library to add MongoDB Persistance to normal Ruby objects}
|
38
|
+
s.test_files = [
|
39
|
+
"spec/mongo_persist_spec.rb",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
|
43
|
+
if s.respond_to? :specification_version then
|
44
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
45
|
+
s.specification_version = 3
|
46
|
+
|
47
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
48
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
49
|
+
s.add_runtime_dependency(%q<fattr>, [">= 0"])
|
50
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
51
|
+
else
|
52
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
53
|
+
s.add_dependency(%q<fattr>, [">= 0"])
|
54
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
55
|
+
end
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
58
|
+
s.add_dependency(%q<fattr>, [">= 0"])
|
59
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
60
|
+
end
|
61
|
+
end
|
data/spec/mongo_persist_spec.rb
CHANGED
@@ -6,17 +6,24 @@ end
|
|
6
6
|
|
7
7
|
class Order
|
8
8
|
include MongoPersist
|
9
|
-
attr_accessor :po_number
|
9
|
+
attr_accessor :po_number, :customers, :some_hash
|
10
|
+
mongo_reference_attributes ['customers']
|
10
11
|
fattr(:order_products) { [] }
|
11
12
|
def products
|
12
13
|
order_products.map { |x| x.product }
|
13
14
|
end
|
15
|
+
def subtotal
|
16
|
+
order_products.map { |x| x.subtotal }.sum
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
class OrderProduct
|
17
21
|
include MongoPersist
|
18
22
|
attr_accessor :unit_price, :quantity, :product
|
19
23
|
mongo_reference_attributes ['product']
|
24
|
+
def subtotal
|
25
|
+
quantity.to_f * unit_price
|
26
|
+
end
|
20
27
|
end
|
21
28
|
|
22
29
|
class Product
|
@@ -24,15 +31,22 @@ class Product
|
|
24
31
|
attr_accessor :name
|
25
32
|
end
|
26
33
|
|
34
|
+
class Customer
|
35
|
+
include MongoPersist
|
36
|
+
attr_accessor :email
|
37
|
+
end
|
38
|
+
|
27
39
|
# too many assertions per test, too many "this is how things should be before i check the point of this test" assertions
|
28
40
|
describe MongoPersist do
|
29
41
|
before do
|
42
|
+
$abc = false
|
30
43
|
[Order,Product].each { |x| x.collection.remove }
|
31
|
-
@products = [Product.new(:name => 'Leather Couch'),Product.new(:name => 'Maroon Chair')].each { |x| x.
|
44
|
+
@products = [Product.new(:name => 'Leather Couch'),Product.new(:name => 'Maroon Chair')].each { |x| x.mongo.save! }
|
45
|
+
@customers = [Customer.new(:email => 'a'),Customer.new(:email => 'b')].each { |x| x.mongo.save! }
|
32
46
|
|
33
47
|
@orders = []
|
34
|
-
@orders << Order.new(:po_number => 1234, :order_products => [OrderProduct.new(:unit_price => 1000, :quantity => 1, :product => @products[0])]).
|
35
|
-
@orders << Order.new(:po_number => 1235, :order_products => [OrderProduct.new(:unit_price => 200, :quantity => 2, :product => @products[1])]).
|
48
|
+
@orders << Order.new(:customers => @customers, :po_number => 1234, :order_products => [OrderProduct.new(:unit_price => 1000, :quantity => 1, :product => @products[0])]).mongo.save!
|
49
|
+
@orders << Order.new(:customers => @customers, :po_number => 1235, :order_products => [OrderProduct.new(:unit_price => 200, :quantity => 2, :product => @products[1])]).mongo.save!
|
36
50
|
end
|
37
51
|
it 'should have id' do
|
38
52
|
@orders.first.mongo_id.should be
|
@@ -53,13 +67,23 @@ describe MongoPersist do
|
|
53
67
|
h.to_mongo_object.name.should == 'Leather Couch'
|
54
68
|
end
|
55
69
|
it 'updates' do
|
56
|
-
@products.first.from_hash(:name => 'White Leather Couch').
|
70
|
+
@products.first.from_hash(:name => 'White Leather Couch').mongo.save!
|
57
71
|
Product.collection.find.count.should == 2
|
58
72
|
Product.collection.find_objects(:name => /Leather/).count.should == 1
|
59
73
|
Product.collection.find_one_object(:name => /Leather/).name.should == 'White Leather Couch'
|
60
74
|
end
|
61
75
|
it 'reference loading' do
|
62
|
-
@products.first.from_hash(:name => 'White Leather Couch').
|
76
|
+
@products.first.from_hash(:name => 'White Leather Couch').mongo.save!
|
63
77
|
Order.collection.find_one_object(:po_number => 1234).products.first.name.should == 'White Leather Couch'
|
64
78
|
end
|
79
|
+
it 'customers' do
|
80
|
+
@customers.first.from_hash(:email => 'z').mongo.save!
|
81
|
+
Order.collection.find_one_object.customers.first.email.should == 'z'
|
82
|
+
end
|
83
|
+
it 'saving hashes' do
|
84
|
+
o = Order.new(:po_number => 1, :some_hash => {'1' => Product.new(:name => 'Chair')})
|
85
|
+
o.mongo.save!
|
86
|
+
Order.collection.find_one_object(:po_number => 1).some_hash['1'].name.should == 'Chair'
|
87
|
+
Order.collection.find_one_object.subtotal.should == 1000
|
88
|
+
end
|
65
89
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongo_persist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Harris
|
@@ -59,7 +59,9 @@ files:
|
|
59
59
|
- Rakefile
|
60
60
|
- VERSION
|
61
61
|
- lib/mongo_persist.rb
|
62
|
+
- lib/mongo_persist/sandbox.rb
|
62
63
|
- lib/mongo_persist/util.rb
|
64
|
+
- mongo_persist.gemspec
|
63
65
|
- spec/mongo_persist_spec.rb
|
64
66
|
- spec/spec_helper.rb
|
65
67
|
has_rdoc: true
|