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
Support a dynamic collection name #4556
Support a dynamic collection name #4556
Conversation
Just to make sure I understand, does this patch propose the following behavior: class Band include Mongoid::Document store_in collection: "artists" end # anywhere in the code Band.with(collection: 'poets') # anywhere else in the code at a later time # queries poets, not artists Band.all |
Not at all, the persistence context is not modified when
Calling |
OK, I am playing with this and I am not yet sold on the type of result of #with being argument-dependent: Band.with(collection: foo) # => Mongoid::Criteria Band.with(collection: foo, database: bar) # => Error: no block given Band.with(collection: foo, database: bar) { |c| } # => Band, c is also Band |
When you say that creating a persistence context is "extremely inefficient", can you describe your use case and performance you are getting in greater detail please? |
Makes sense that we should probably not override the existing Create a document in the Band.create!(collection_name: 'other', name: 'U2') Find the document in the band = Band.with_colllection('other').first Somewhere else in the application make changes and save the document without having to know which collection this document came from: band.rating = 45
band.save! |
Can you elaborate on performance issues you are having with the existing implementation? |
The purpose of this pull request has nothing to do with performance, it is to obtain the above functionality so as to remove the burden from developers to have to figure out which collection a document came from in order to modify it. |
Okay, then, will a non-block form of # collection change only band = Band.with(collection: 'other_bands').where(name: "Depeche Mode").first band.rating = 23 band.save! # db and collection change band = Band.with(db: 'foo', collection: 'other_bands').where(name: "Depeche Mode").first band.rating = 23 band.save! |
Yes |
I agree we should add a non-block form of |
I created https://jira.mongodb.org/browse/MONGOID-4629 to track the work on a non-block form of #with. |
Close this PR in favor of the above ticket |
Sometimes we want to create a model and then use that model for different Mongo collections, ideally chosen dynamically at run-time.
For Example, for a static one-to-one mapping between a model and its class:
Dynamically changing the collection name at run-time:
In Mongoid 5.4, the above kind of worked. It was extremely inefficient and led to all kinds of problems because every call to
with
resulted in a brand new persistence context. Additionally, thesave!
would not save the changed document back to theother_bands
collection.In Mongoid 6/7 it uses a block in order to cleanup the persistence context on completion:
Even in the above case, creating a brand new persistence context when only the
collection_name
has changed is extremely inefficient, and it requires the constant use of the block anytime a modified document is saved.How about we make
collection
a special case since it does not need a new persistence context every time the collection name is changed. And, if we make the instance of the model remember its collection name then we don't have to complicate any code that attempts to persist any changes to that document.That would make the following code possible:
Or even allow the collection name to be supplied directly when creating a new model: