Skip to content

Instantly share code, notes, and snippets.

@jsmestad
Created May 26, 2011 20:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jsmestad/993978 to your computer and use it in GitHub Desktop.
Save jsmestad/993978 to your computer and use it in GitHub Desktop.
Proposed changes for Mongomatic 0.9.0
@snapshot = Snapshot.first
-----
{
:stats => {
'accounts' => { 'count' => 8 },
'subscriptions' => { 'count' => 16 }
},
:activity => [ {'ns' => 'accounts.users', ...}, {'ns' => 'subscriptions.users' =>, ...} ]
}
-----
# Attribute definitions would be defined as instance method accessors
#
# For example:
# def database_id; self.doc[:database_id]; end
@snapshot.database_id
@snapshot.created_at
@snapshot.stats
----
@snapshot.select('stats.*', :count => 16) # would search all sub-hashes that match the query, returning the hash containing the value
@snapshot.select('activity.*', :ns => /^accounts\.$/) # would return the sub-hash that matches the query in the array
-----
@snapshot['stats.accounts.count'] # => 8
@snapshot['stats.posts.count'] # => nil
@snapshot.doc(['stats.posts.count'], true|false) # => KeyDoesNotExist, 'stats.posts does not exist in the document hash, true is the default here as your assuming the hash exists at the doc level
# Assignment -- not sure about this one.
@snapshot['stats.posts.count'] = 8 # => {:stats => { 'posts' => { 'count' => 8 } } } but raise error if the type is an Array.
@snapshot['stats.*.count'] = 8 # => mass assignment to doc[:stats].each {|x| x[:count] = 8 }
class Snapshot
include Mongomatic # this will replace Mongomatic::Base, its like saying 'normal defaults'
include Mongomatic::Sanitize
attribute :database_id, :typed => Integer, :required => true
attribute :created_at, :typed => Time, :required => true
attribute :stats, :typed => Hash, :required => true
sanitize_keys # will do the entire document
sanitize_keys :stats, :replace_with => '#', :depth => 2 # various options we could support
indexes do |collection|
collection.ensure_index([['database_id', Mongo::ASCENDING], ['created_at', Mongo::DESCENDING]], :unique => true)
end
end
@jrwest
Copy link

jrwest commented Jun 1, 2011

I think object serialization and handling of DateTime/etc objects are something we should address for sure (actually there was a lot of discussing on how to do the latter at the Ruby talk at MongoSF). However, I do think I was addressing a third use case with this: handling data from forms. The mongo driver casts to the correct mongo type but it doesn't cast "1.23" to its float equivalent, etc. If you have a lot of things like checkboxes or textfields to take numbers having some "type casting" like that can reduce/simplify code. IMO, useful when writing something like an admin tool and I think making writing admin screens for Shadelight easier was one of the reasons Ben built typed fields. Also, its not hard to build your own Mongomatic::TypeConverters and have custom "casters", which could lead to some cool stuff. But like I said before, I'm not dead set on implementing it this way, it just happens to be how I was first inclined to build and use it. We can always rip it out and rewrite it with a focus solely on serialization.

For example something like:

 # some rails action
 def my_action
      item_instance = Item.new # some Mongomatic model instance
      item_instance['avail_for_purchase'] = params[:item][:avail_for_purchase] == "1" ? 1 : 0
      item_instance['price'] = params[:item][:price].to_f # lets just hope in this example we get a proper dollar value
      # lots more control statements & setting of values
      #...
 end

just becomes:

 def my_action
    item_instance.new(params[:item])
 end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment