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
Fix bug where BSON ObjectID's wouldn't work #279
Conversation
Fixes for when ObjectID's are traditional mongodb id's - Might need a bit of work on the validation of object ids
@@ -33,6 +33,15 @@ _Mongo = function (url) { | |||
}); | |||
}; | |||
|
|||
//Check whether the object id is valid | |||
_Mongo._isObjectId = function(objectid) { | |||
if(objectid.length == 24) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a little magical to me. Why 24? Is there a link you can provide to document this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its from the spec, ObjectID's are 12 bytes - 24 characters long
Validation could be better
Thanks for the pull request. Here are some initial comments. I also admit that I am not personally very familiar with these BSON ObjectIDs. Can you add a test to mongo_livedata_tests.js that demonstrates the issue that this solves, and ensures that we don't break your fix in the future? Have you submitted a CLA yet? See http://contribute.meteor.com/ |
So I'm a little confused about the context where this happens. Is this only if the user actually does a collection.update({ _id: "abcdefabcdef12345612346" })? Isn't the answer just to make sure the user inserts the MongoDB.BSONPure.ObjectId call in this case? Or is there some place in Meteor where Meteor strips the ObjectId-ness? Do you have a test case for the bug? |
Yes using MongoDB.BSONPure.ObjectId would fix the problem but MongoDB is out of context (im not sure) within Meteor js files but I've been trying all sorts of things that way, it should just work with a string as an id. A test case would be to connect to the mongodb via the console and add a document with an objectid:
Then try accessing this via Meteor
or even
None of these would work but they should. |
In my opinion it should be this way with the strings instead of putting in a BSONPure.ObjectId because:
Works and it would be best to maintain a consistency of the paradigm across to update and remove |
For what it's worth, when I tested this, people.findOne('47cc67093475061e3d95369d') did not work. I do agree that having to type MongoDB.BSONPure.ObjectID is painful, though, but the magic treatment of 24-character strings is not great. I'd prefer either: (a) Importing MongoDB.BSONPure.ObjectID into the Meteor namespace somewhere The latter is my preference but it's a bit annoying: Meteor.Collection doesn't take an options object yet, the _rewriteSelector function doesn't have access to the Collection object, etc. But I think in the long run, saying "You can use arbitrary JSON objects as your _id... but if they are strings they can't be 24 characters wrong" is not an interface I'd be excited about supporting. |
What about validating whether the id's are BSON objectids by checking they are not only 24 characters, but hex and to the spec of an objectid so that no other string can pass off as an objectid? That was my original idea but I was looking to use the BSONPure.ObjectId.isValid method but I can't seem to get it to work properly. The way meteor is designed is to be as close to 'magic' and having it 'just work' as possible. What do you think of checking whether its an ObjectID to spec over the options you presented? |
That was my original plan, if I can get _isObjectId() to work efficiently so not every string can pass off, but only one which is actually an objectid then its less painstaking and more magical. The idea of meteor is to take away as much of the hassle as possible. |
Im able to get findOne() and find() to work with id's. They've not been created the same way in the mongo console, rather via Mongoid and rails but it should be the same thing |
I just got bit by this one as well. It definitely seems like it would be most Meteor/magical (and best for the framework) to invisibly handle the conversion. |
@Tarangp I can verify that findOne() and find() work for me too (whether they have ObjectId's or Meteor IDs or any other string ID). It's just the collection modification methods that are failing. @glasser I'm not sure either option will work. For a), I don't think on the client, we can properly detect the ObjectID-ness of an id. My brief look at the minimongo source makes me think that ObjectIds never make it to the client - they are transformed into strings in minimongo no matter what. (Of course, that could be entirely wrong...) When I do a find() on the client, the object I get has the _id field as a string whether it's an ObjectId or not in Mongo. If the ObjectId object is preserved in minimongo, we could just use 'instanceof' to properly handle it but it currently won't work... (I suppose if the _id were any immutable object, we could keep the _id object and pass it as a token and have the proper behavior). For b) as an example, we have some documents created using Meteor which doesn't use ObjectIds for object IDs and some being imported from foreign systems that do use ObjectIDs in the same collection. A collection-wide option like b) would break update code for some of the documents either way... (unless the flag forced Meteor to also create all new documents using ObjectId's too.) |
Taking a further look at this, I notice that even in direct Mongo shell, 24-character strings aren't handled specially:
So I don't think handling them magically in Meteor is correct. But we should probably offer some function to convert to Mongo ObjectIds (which should work in the client too). |
I added a bunch of comments to the initial issue, #61. Because I don't believe that this pull request is the right direction towards fixing the issue, I'm going to close the pull request for now, but leave the issue open. |
Package articles content
Fixes selector driver so documents querieid with traditional bson objectid's can be updated, removed.. etc
Might need some work on objectid validation