mongo_mapper 0.9.1 → 0.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -44,7 +44,7 @@ module MongoMapper
44
44
 
45
45
  # @api private
46
46
  def config_for_environment(environment)
47
- env = config[environment]
47
+ env = config[environment] || {}
48
48
  return env if env['uri'].blank?
49
49
 
50
50
  uri = URI.parse(env['uri'])
@@ -61,7 +61,13 @@ module MongoMapper
61
61
  def connect(environment, options={})
62
62
  raise 'Set config before connecting. MongoMapper.config = {...}' if config.blank?
63
63
  env = config_for_environment(environment)
64
- MongoMapper.connection = Mongo::Connection.new(env['host'], env['port'], options)
64
+
65
+ MongoMapper.connection = if env['hosts']
66
+ Mongo::ReplSetConnection.new( *env['hosts'].push(options) )
67
+ else
68
+ Mongo::Connection.new(env['host'], env['port'], options)
69
+ end
70
+
65
71
  MongoMapper.database = env['database']
66
72
  MongoMapper.database.authenticate(env['username'], env['password']) if env['username'] && env['password']
67
73
  end
@@ -4,13 +4,13 @@ module MongoMapper
4
4
  module ActiveModel
5
5
  extend ActiveSupport::Concern
6
6
 
7
- include ::ActiveModel::Naming
8
7
  include ::ActiveModel::Conversion
9
8
  include ::ActiveModel::Serialization
10
9
  include ::ActiveModel::Serializers::Xml
11
10
  include ::ActiveModel::Serializers::JSON
12
11
 
13
12
  included do
13
+ extend ::ActiveModel::Naming
14
14
  extend ::ActiveModel::Translation
15
15
  end
16
16
  end
@@ -5,11 +5,6 @@ module MongoMapper
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  module InstanceMethods
8
- def valid?(context = nil)
9
- context ||= (new_record? ? :create : :update)
10
- super(context) && errors.empty?
11
- end
12
-
13
8
  def destroy
14
9
  run_callbacks(:destroy) { super }
15
10
  end
@@ -6,9 +6,8 @@ module MongoMapper
6
6
 
7
7
  included do
8
8
  extend ::ActiveModel::Callbacks
9
- include ::ActiveModel::Validations::Callbacks
10
9
 
11
- define_model_callbacks :validation, :save, :create, :update, :destroy, :only => [:before, :after]
10
+ define_model_callbacks :save, :create, :update, :destroy, :only => [:before, :after]
12
11
  end
13
12
 
14
13
  module InstanceMethods
@@ -32,12 +31,3 @@ module MongoMapper
32
31
  end
33
32
  end
34
33
  end
35
-
36
- # Need to monkey patch ActiveModel for now since it uses the internal
37
- # _run_validation_callbacks, which is impossible to override due to the
38
- # way ActiveSupport::Callbacks is implemented.
39
- ActiveModel::Validations::Callbacks.class_eval do
40
- def run_validations!
41
- run_callbacks(:validation) { super }
42
- end
43
- end
@@ -5,8 +5,9 @@ module MongoMapper
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  module InstanceMethods
8
- def inspect
9
- attributes_as_nice_string = key_names.sort.collect do |name|
8
+ def inspect(include_nil = false)
9
+ keys = include_nil ? key_names : attributes.keys
10
+ attributes_as_nice_string = keys.sort.collect do |name|
10
11
  "#{name}: #{self[name].inspect}"
11
12
  end.join(", ")
12
13
  "#<#{self.class} #{attributes_as_nice_string}>"
@@ -193,7 +193,7 @@ module MongoMapper
193
193
 
194
194
  def attributes
195
195
  HashWithIndifferentAccess.new.tap do |attrs|
196
- keys.each_pair do |name, key|
196
+ keys.select { |name,key| !self[key.name].nil? || key.type == ObjectId }.each do |name, key|
197
197
  value = key.set(self[key.name])
198
198
  attrs[name] = value
199
199
  end
@@ -322,3 +322,4 @@ module MongoMapper
322
322
  end
323
323
  end
324
324
  end
325
+
@@ -140,8 +140,7 @@ module MongoMapper
140
140
  module InstanceMethods
141
141
  def save(options={})
142
142
  options.assert_valid_keys(:validate, :safe)
143
- options.reverse_merge!(:validate => true)
144
- !options[:validate] || valid? ? create_or_update(options) : false
143
+ create_or_update(options)
145
144
  end
146
145
 
147
146
  def save!(options={})
@@ -4,6 +4,10 @@ module MongoMapper
4
4
  module Sci
5
5
  extend ActiveSupport::Concern
6
6
 
7
+ included do
8
+ extend ActiveSupport::DescendantsTracker
9
+ end
10
+
7
11
  module ClassMethods
8
12
  def inherited(subclass)
9
13
  key :_type, String unless key?(:_type)
@@ -18,7 +22,7 @@ module MongoMapper
18
22
 
19
23
  def query(options={})
20
24
  super.tap do |query|
21
- query[:_type] = name if single_collection_inherited?
25
+ query[:_type] = {'$in' => [name] + descendants.map(&:name)} if single_collection_inherited?
22
26
  end
23
27
  end
24
28
  end
@@ -31,4 +35,4 @@ module MongoMapper
31
35
  end
32
36
  end
33
37
  end
34
- end
38
+ end
@@ -102,6 +102,11 @@ module MongoMapper
102
102
  def attributes_hash
103
103
  @serializable.serializable_hash(options)
104
104
  end
105
+
106
+ def serializable_methods
107
+ # Methods are already included in #serializable_hash
108
+ []
109
+ end
105
110
  end
106
111
  end
107
112
  end
@@ -5,11 +5,12 @@ module MongoMapper
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  module ClassMethods
8
- def userstamps!
8
+ def userstamps!(options = {})
9
+ class_name = (options[:class_name] || options[:class] || 'User' ).to_s
9
10
  key :creator_id, ObjectId
10
11
  key :updater_id, ObjectId
11
- belongs_to :creator, :class_name => 'User'
12
- belongs_to :updater, :class_name => 'User'
12
+ belongs_to :creator, :class_name => class_name
13
+ belongs_to :updater, :class_name => class_name
13
14
  end
14
15
  end
15
16
  end
@@ -5,6 +5,7 @@ module MongoMapper
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  include ::ActiveModel::Validations
8
+ include ::ActiveModel::Validations::Callbacks
8
9
 
9
10
  module ClassMethods
10
11
  def validates_uniqueness_of(*attr_names)
@@ -16,6 +17,18 @@ module MongoMapper
16
17
  end
17
18
  end
18
19
 
20
+ module InstanceMethods
21
+ def save(options = {})
22
+ options.reverse_merge!(:validate => true)
23
+ !options[:validate] || valid? ? super : false
24
+ end
25
+
26
+ def valid?(context = nil)
27
+ context ||= (new_record? ? :create : :update)
28
+ super(context)
29
+ end
30
+ end
31
+
19
32
  class UniquenessValidator < ::ActiveModel::EachValidator
20
33
  def initialize(options)
21
34
  super(options.reverse_merge(:case_sensitive => true))
@@ -64,3 +77,12 @@ module MongoMapper
64
77
  end
65
78
  end
66
79
  end
80
+
81
+ # Need to monkey patch ActiveModel for now since it uses the internal
82
+ # _run_validation_callbacks, which is impossible to override due to the
83
+ # way ActiveSupport::Callbacks is implemented.
84
+ ActiveModel::Validations::Callbacks.class_eval do
85
+ def run_validations!
86
+ run_callbacks(:validation) { super }
87
+ end
88
+ end
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module MongoMapper
3
- Version = '0.9.1'
3
+ Version = '0.9.2'
4
4
  end
@@ -155,4 +155,31 @@ class CallbacksTest < Test::Unit::TestCase
155
155
  end
156
156
  end
157
157
  end
158
+
159
+ context "Running validation callbacks with conditional execution" do
160
+ setup do
161
+ @document = Doc do
162
+ include CallbacksSupport
163
+ key :message, String
164
+
165
+ before_validation :set_message, :on => 'create'
166
+ def set_message
167
+ self['message'] = 'Hi!'
168
+ end
169
+ end
170
+ end
171
+
172
+ should 'run callback on create' do
173
+ doc = @document.create
174
+ doc.history.should include(:before_validation)
175
+ doc.message.should == 'Hi!'
176
+ end
177
+
178
+ should 'skip callback on update' do
179
+ doc = @document.create
180
+ doc.message = 'Ho!'
181
+ doc.save
182
+ doc.message.should == 'Ho!'
183
+ end
184
+ end
158
185
  end
@@ -12,6 +12,7 @@ class SciTest < Test::Unit::TestCase
12
12
  class ::DocDaughter < ::DocParent; end
13
13
  class ::DocSon < ::DocParent; end
14
14
  class ::DocGrandSon < ::DocSon; end
15
+ class ::DocGrandGrandSon < ::DocGrandSon; end
15
16
 
16
17
  DocSon.many :children, :class_name => 'DocGrandSon'
17
18
 
@@ -24,6 +25,7 @@ class SciTest < Test::Unit::TestCase
24
25
  Object.send :remove_const, 'DocDaughter' if defined?(::DocDaughter)
25
26
  Object.send :remove_const, 'DocSon' if defined?(::DocSon)
26
27
  Object.send :remove_const, 'DocGrandSon' if defined?(::DocGrandSon)
28
+ Object.send :remove_const, 'DocGrandGrandSon' if defined?(::DocGrandGrandSon)
27
29
  end
28
30
 
29
31
  should "automatically add _type key to store class" do
@@ -86,11 +88,19 @@ class SciTest < Test::Unit::TestCase
86
88
  steve = DocSon.create(:name => 'Steve')
87
89
  steph = DocDaughter.create(:name => 'Steph')
88
90
  carrie = DocDaughter.create(:name => 'Carrie')
91
+ boris = DocGrandSon.create(:name => 'Boris')
89
92
 
90
- DocGrandSon.all(:order => 'name').should == []
91
- DocSon.all(:order => 'name').should == [john, steve]
93
+ DocGrandGrandSon.all(:order => 'name').should == []
94
+ DocGrandSon.all(:order => 'name').should == [boris]
95
+ DocSon.all(:order => 'name').should == [boris, john, steve]
92
96
  DocDaughter.all(:order => 'name').should == [carrie, steph]
93
- DocParent.all(:order => 'name').should == [carrie, john, steph, steve]
97
+ DocParent.all(:order => 'name').should == [boris, carrie, john, steph, steve]
98
+
99
+ sigmund = DocGrandGrandSon.create(:name => 'Sigmund')
100
+
101
+ DocGrandSon.all(:order => 'name').should == [boris, sigmund]
102
+ DocSon.all(:order => 'name').should == [boris, john, sigmund, steve]
103
+ DocParent.all(:order => 'name').should == [boris, carrie, john, sigmund, steph, steve]
94
104
  end
95
105
 
96
106
  should "work with nested hash conditions" do
@@ -227,4 +237,4 @@ class SciTest < Test::Unit::TestCase
227
237
  Child.new(:_type => 'OtherChild')._type.should == 'Child'
228
238
  end
229
239
  end
230
- end
240
+ end
@@ -1,27 +1,44 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class UserstampsTest < Test::Unit::TestCase
4
+ class AltUser
5
+ include MongoMapper::Document
6
+ end
7
+
4
8
  context "userstamping" do
5
9
  setup do
6
10
  @document = Doc do
7
11
  userstamps!
8
12
  end
13
+ @document_alt_user = Doc do
14
+ userstamps! :class_name => 'AltUser'
15
+ end
16
+ @document_alt_user_class = Doc do
17
+ userstamps! :class => AltUser
18
+ end
19
+ @docs = [@document, @document_alt_user, @document_alt_user_class]
9
20
  end
10
21
 
11
22
  should "add creator_id key" do
12
- @document.keys.keys.should include('creator_id')
23
+ @docs.each{ |d| d.keys.should include('creator_id') }
13
24
  end
14
25
 
15
26
  should "add updater_id key" do
16
- @document.keys.keys.should include('updater_id')
27
+ @docs.each{ |d| d.keys.should include('updater_id') }
17
28
  end
18
29
 
19
30
  should "add belongs_to creator" do
20
- @document.associations.keys.should include(:creator)
31
+ @docs.each{ |d| d.associations.keys.should include(:creator) }
21
32
  end
22
33
 
23
34
  should "add belongs_to updater" do
24
- @document.associations.keys.should include(:updater)
35
+ @docs.each{ |d| d.associations.keys.should include(:updater) }
36
+ end
37
+
38
+ should "properly set class names" do
39
+ @document.associations[:creator].class_name.should == 'User'
40
+ @document_alt_user.associations[:creator].class_name.should == 'AltUser'
41
+ @document_alt_user_class.associations[:creator].class_name.should == 'UserstampsTest::AltUser'
25
42
  end
26
43
  end
27
44
  end
data/test/models.rb CHANGED
@@ -241,3 +241,7 @@ module News
241
241
  include MongoMapper::Document
242
242
  end
243
243
  end
244
+
245
+ class AltUser
246
+ include MongoMapper::Document
247
+ end
@@ -10,4 +10,9 @@ class ActiveModelLintTest < ActiveModel::TestCase
10
10
  def setup
11
11
  @model = Post.new
12
12
  end
13
+
14
+ def test_naming
15
+ Post.model_name.plural.should == 'posts'
16
+ Post.new.respond_to?(:model_name).should be_false
17
+ end
13
18
  end
data/test/test_helper.rb CHANGED
@@ -1,29 +1,24 @@
1
1
  require 'rubygems'
2
2
  require 'bundler/setup'
3
3
 
4
- $:.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
4
+ $:.unshift File.expand_path('../../lib', __FILE__)
5
5
  require 'mongo_mapper'
6
6
  require 'fileutils'
7
7
  require 'ostruct'
8
8
 
9
- require 'json'
10
- require 'log_buddy'
11
- require 'matchy'
12
- require 'shoulda'
13
- require 'timecop'
14
- require 'mocha'
15
- require 'ruby-debug'
9
+ Bundler.require(:development)
16
10
 
17
11
  class Test::Unit::TestCase
18
12
  def Doc(name='Class', &block)
19
13
  klass = Class.new
20
14
  klass.class_eval do
21
15
  include MongoMapper::Document
22
- set_collection_name :test
23
16
 
24
17
  if name
25
18
  class_eval "def self.name; '#{name}' end"
26
19
  class_eval "def self.to_s; '#{name}' end"
20
+ else
21
+ set_collection_name :test
27
22
  end
28
23
  end
29
24
 
@@ -145,6 +145,9 @@ class XmlSerializationTest < Test::Unit::TestCase
145
145
  assert_no_match %r{awesome}, xml
146
146
  assert_no_match %r{created-at}, xml
147
147
  assert_no_match %r{preferences}, xml
148
+
149
+ # Assert only one tag is created
150
+ xml.scan(/favorite-quote/).size.should == 2
148
151
  end
149
152
  end
150
153
 
@@ -204,5 +204,46 @@ class DocumentTest < Test::Unit::TestCase
204
204
  (@document.new('_id' => @oid) == another_document.new('_id' => @oid)).should be(false)
205
205
  end
206
206
  end
207
+
208
+ context "nil attributes" do
209
+
210
+ should "list all the keys and default non nil attributes" do
211
+ doc = @document.new
212
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
213
+ doc.attributes.keys.sort.should == ['_id']
214
+ end
215
+
216
+ should "list all the keys and non nil attributes" do
217
+ doc = @document.new(:name => "John")
218
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
219
+ doc.attributes.keys.sort.should == ['_id','name']
220
+ end
221
+
222
+ should "list all the keys and pickup changed nil attributes" do
223
+ doc = @document.new(:name => "John")
224
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
225
+ doc.attributes.keys.sort.should == ['_id','name']
226
+
227
+ doc.name = nil
228
+
229
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
230
+ doc.attributes.keys.sort.should == ['_id']
231
+ end
232
+
233
+ should "list all the keys and pickup changed nil and non-nil attributes" do
234
+ doc = @document.new(:name => "John")
235
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
236
+ doc.attributes.keys.sort.should == ['_id','name']
237
+
238
+ doc.name = nil
239
+ doc.age = 12
240
+
241
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
242
+ doc.attributes.keys.sort.should == ['_id','age']
243
+ end
244
+
245
+ end
246
+
207
247
  end # instance of a document
208
248
  end # DocumentTest
249
+
@@ -364,14 +364,16 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
364
364
  context "attributes" do
365
365
  should "default to hash with all keys" do
366
366
  doc = @document.new
367
- doc.attributes.keys.sort.should == ['_id', 'age', 'name']
367
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
368
+ doc.attributes.keys.sort.should == ['_id']
368
369
  end
369
370
 
370
371
  should "return all keys with values" do
371
372
  doc = @document.new(:name => 'string', :age => nil)
372
- doc.attributes.keys.sort.should == ['_id', 'age', 'name']
373
+ doc.attributes.keys.sort.should == ['_id', 'name']
374
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
373
375
  doc.attributes.values.should include('string')
374
- doc.attributes.values.should include(nil)
376
+ doc.attributes.values.should_not include(nil)
375
377
  end
376
378
 
377
379
  should "have indifferent access" do
@@ -384,14 +386,16 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
384
386
  context "to_mongo" do
385
387
  should "default to hash with _id key" do
386
388
  doc = @document.new
387
- doc.to_mongo.keys.sort.should == ['_id', 'age', 'name']
389
+ doc.to_mongo.keys.sort.should == ['_id']
390
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
388
391
  end
389
392
 
390
393
  should "return all keys" do
391
394
  doc = @document.new(:name => 'string', :age => nil)
392
- doc.to_mongo.keys.sort.should == ['_id', 'age', 'name']
395
+ doc.keys.keys.sort.should == ['_id', 'age', 'name']
396
+ doc.to_mongo.keys.sort.should == ['_id','name']
393
397
  doc.to_mongo.values.should include('string')
394
- doc.to_mongo.values.should include(nil)
398
+ doc.to_mongo.values.should_not include(nil)
395
399
  end
396
400
  end
397
401
 
@@ -675,3 +679,4 @@ class EmbeddedDocumentTest < Test::Unit::TestCase
675
679
  end # instance of a embedded document
676
680
  end
677
681
  end
682
+
@@ -5,7 +5,7 @@ class SupportTest < Test::Unit::TestCase
5
5
  should "convert value to_a" do
6
6
  Array.to_mongo([1, 2, 3, 4]).should == [1, 2, 3, 4]
7
7
  Array.to_mongo('1').should == ['1']
8
- Array.to_mongo({'1' => '2', '3' => '4'}).should == [['1', '2'], ['3', '4']]
8
+ Array.to_mongo({'1' => '2', '3' => '4'}).should include(['1', '2'], ['3', '4'])
9
9
  end
10
10
  end
11
11
 
@@ -6,14 +6,19 @@ class InspectTest < Test::Unit::TestCase
6
6
  @document = Doc('User') do
7
7
  key :name, String
8
8
  key :age, Integer
9
+ key :email, String
9
10
  end
10
11
 
11
12
  @doc = @document.new(:name => 'John', :age => 29)
12
13
  end
13
14
 
14
- should "print out attributes in alpha sorted order" do
15
+ should "print out non-nil attributes in alpha sorted order" do
15
16
  @doc.inspect.should =~ /_id:.*, age: 29, name: "John"/
16
17
  end
18
+
19
+ should "print out all attributes when (optional) include_super argument is true" do
20
+ @doc.inspect(true).should =~ /_id:.*, age: 29, email: nil, name: "John"/
21
+ end
17
22
 
18
23
  should "include class name" do
19
24
  @doc.inspect.should =~ /^#<User/
@@ -96,6 +96,20 @@ class MongoMapperTest < Test::Unit::TestCase
96
96
  }
97
97
  assert_raises(MongoMapper::InvalidScheme) { MongoMapper.connect('development') }
98
98
  end
99
+
100
+ should "create a replica set connection if config contains multiple hosts" do
101
+ MongoMapper.config = {
102
+ 'development' => {
103
+ 'hosts' => [ ['127.0.0.1', 27017], ['localhost', 27017] ],
104
+ 'database' => 'test'
105
+ }
106
+ }
107
+
108
+ Mongo::ReplSetConnection.expects(:new).with( ['127.0.0.1', 27017], ['localhost', 27017], {'read_secondary' => true} )
109
+ MongoMapper.expects(:database=).with('test')
110
+ Mongo::DB.any_instance.expects(:authenticate).never
111
+ MongoMapper.connect('development', 'read_secondary' => true)
112
+ end
99
113
  end
100
114
 
101
115
  context "setup" do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_mapper
3
3
  version: !ruby/object:Gem::Version
4
- hash: 57
4
+ hash: 63
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 9
9
- - 1
10
- version: 0.9.1
9
+ - 2
10
+ version: 0.9.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - John Nunemaker
@@ -15,11 +15,14 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-17 00:00:00 -04:00
18
+ date: 2011-09-02 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
22
- requirement: &id001 !ruby/object:Gem::Requirement
22
+ name: activemodel
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
23
26
  none: false
24
27
  requirements:
25
28
  - - ~>
@@ -29,12 +32,12 @@ dependencies:
29
32
  - 3
30
33
  - 0
31
34
  version: "3.0"
32
- prerelease: false
33
- version_requirements: *id001
34
- type: :runtime
35
- name: activemodel
35
+ requirement: *id001
36
36
  - !ruby/object:Gem::Dependency
37
- requirement: &id002 !ruby/object:Gem::Requirement
37
+ name: activesupport
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: &id002 !ruby/object:Gem::Requirement
38
41
  none: false
39
42
  requirements:
40
43
  - - ~>
@@ -44,12 +47,12 @@ dependencies:
44
47
  - 3
45
48
  - 0
46
49
  version: "3.0"
47
- prerelease: false
48
- version_requirements: *id002
49
- type: :runtime
50
- name: activesupport
50
+ requirement: *id002
51
51
  - !ruby/object:Gem::Dependency
52
- requirement: &id003 !ruby/object:Gem::Requirement
52
+ name: plucky
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
53
56
  none: false
54
57
  requirements:
55
58
  - - ~>
@@ -60,10 +63,7 @@ dependencies:
60
63
  - 3
61
64
  - 8
62
65
  version: 0.3.8
63
- prerelease: false
64
- version_requirements: *id003
65
- type: :runtime
66
- name: plucky
66
+ requirement: *id003
67
67
  description:
68
68
  email:
69
69
  - nunemaker@gmail.com
@@ -268,7 +268,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
268
268
  requirements: []
269
269
 
270
270
  rubyforge_project:
271
- rubygems_version: 1.4.2
271
+ rubygems_version: 1.6.1
272
272
  signing_key:
273
273
  specification_version: 3
274
274
  summary: A Ruby Object Mapper for Mongo