Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various new features #1

Open
wants to merge 61 commits into
base: master
Choose a base branch
from

Conversation

CodeMonkeySteve
Copy link
Contributor

As a former user of MongoMapper, and a current frustrated user of Mongoid, I'm very excited about MongoODM and the design you've implemented. I'd like to start using it for production projects, but there are a few critical features I still need. I've implemented a few here, and will add more in the future:

  • Formal config loading and lazy connection (for use with em-synchrony)
  • Document timestamps
  • Callbacks on 'create' and 'update'
  • Executing callbacks on all embedded documents. This was a tricky one.
  • A Reference type. I prefer this solution over "associations", as it's both simpler and much more Ruby-like. You can mix-and-match References with other field types or with other values in an Array. Since dereferencing is done lazily, it might not be as efficient in cases where you want to load a large number of objects, and in the future I may add a ReferenceArray class to fix this.

See the tests for basic usage information.

@carlosparamio
Copy link
Owner

Hi Steve!

These changes are pretty exciting. I've already merged some of them. Here you have some comments:

  • Formal config loading and lazy connection (for use with em-synchrony)

This is great. Specially the railtie file makes MongoODM a lot easier to configure for a Rails application.

  • Document timestamps

Yeah, it has a lot of sense. I was expecting to add some useful modules for MongoODM documents, and keep them on a separated gem. But let's start adding them on this one meanwhile.

  • Callbacks on 'create' and 'update'

There is no 'create' method on the Mongo driver (therefore on any class that includes the MongoODM::Document module). The insert or update of a document is managed by the Mongo driver through the 'id' attribute: If it was already present, it executes an update of the document. If not, it executes an insert. It might have more sense, in my opinion, to have before/after insert callbacks instead of before/after create. Anyway, both the update and insert methods are class methods of MongoODM::Document (actually, of Mongo::Collection), so we might have to explicitly send those callbacks on an instance scope to make them useful, as you have done on the MongoODM::Document::Persistence#save method.

The idea is to mimic the Mongo Ruby driver, not ActiveRecord :-)

These are the reasons why I still haven't merged these other changes to the master. Also, the specs for these changes are failing to me. I'm going to create a new branch called "new_callbacks" on the main repository with your two commits related to this topic, so we can work on a solution on top of this.

  • Executing callbacks on all embedded documents. This was a tricky one.

Yeah. This new feature has made me think on the callbacks cycle for embedded documents. I think it has a lot of sense to send a message to all the embedded documents present on a MongoODM::Document instance, so if the "parent" document was saved they can receive also the appropiate calls. However, this is failing to me. I'll also add it to the "new_callbacks" branch.

  • A Reference type.

I think this is a clever solution. It allows the developer to specify referenced documents of any type. I like the idea. But I think it is not universal, in the sense that when you know that you're going to save references to just one type of object, it might be an overkill to store a hash with all those attributes (_class, collection, target_id) instead of pure BSON values. For example, if I have a class like:

class User
  include MongoODM::Document
  field :friends_ids, Array
end

If I want to store a list of referenced users at the "friends" array, it has more sense to store just the BSON ids, and instantiate them as User objects when accesed.

The idea for those cases at the end is to have some kind of syntax like "has_many_referenced :friends" that creates the accesor methods that updates the attribute. On the case you're trying to implement, it might be something like "has_many_referenced :friends, :polymorphic => true" to explicitly say that you can save any kind of objects on it. I think this is the way to go.

In any case, I've also experimented some problems when running the specs for this implementation.

Because of these reasons, I haven't merged this other feature on the master branch either. I will create an "experimental-references" branch to keep your contribution anyway, it might be very useful as a base for the implementation I've commented upper.

Thanks a lot for working on this!

Carlos

@CodeMonkeySteve
Copy link
Contributor Author

Added a few more minor fixes.

CodeMonkeySteve and others added 24 commits January 30, 2011 15:42
Conflicts:
	Gemfile
	lib/mongo_odm/criteria.rb
	lib/mongo_odm/errors.rb
Conflicts:
	lib/mongo_odm/document/persistence.rb
	lib/mongo_odm/errors.rb
BSON serializes Time values by rounding to the nearest millisecond.  To keep the pre-serialized value the same as post-serialized, round the value on assignment.
CodeMonkeySteve and others added 30 commits March 24, 2011 11:47
Conflicts:
	lib/mongo_odm/criteria.rb
	lib/mongo_odm/document.rb
	lib/mongo_odm/document/persistence.rb
These should only exist for gems where the version really matters.
don't mark attribute as dirty if it doesn't change
Updates to track attribute method generation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants