vapor-community / mongo-provider

MongoDB Provider for Vapor
40 stars 18 forks source link

"id" not populated on first save #10

Open Noobitious opened 7 years ago

Noobitious commented 7 years ago

I have made a model and saved it to a Mongo DB. My model creates "var id: Node?" and init to "self.id = nil". However, when the record is saved I notice Mongo creates a different "_id" with values like this "ObjectId("31943c580047b1f729e088f5")". The "id" field is left null as you can see here:

screen shot 2016-11-28 at 4 16 04 pm

However, if I do the same thing but save the model twice then it seems to populate the "id" field as you can see here:

screen shot 2016-11-28 at 4 47 27 pm

I believe this should have been done on the first save, but if you have multiple documents, it will arbitrarily update the id of the first document it finds (i.e., not necessarily the correct one)

voronianski commented 7 years ago

I'm experiencing the same issue.

voronianski commented 7 years ago

@tannernelson is it possible to patch data with id here - https://github.com/vapor/fluent/blob/master/Sources/Fluent/Query/Query.swift#L167-L169? Or it's a wrong place?

voronianski commented 7 years ago

@Noobitious I managed to find such workaround until this issue is solved. So you need to actually check if id is nil when creating a Node:

func makeNode(context: Context) throws -> Node {
    var data = [String: Node]()
    data["text"] = Node(text)

    if id != nil {
      data["id"] = id
    }

    return try Node(node: data)
}

UPDATE

I reverted this change because it breaks update of the model (driver somehow doesn't want to update documents without id field) but if you don't need updates this might work.

Noobitious commented 7 years ago

@voronianski I tried to figure it out, but I'm confused between fluent, provider, driver as to where to focus my attention. The model does know the correct "id" right after you create, but it just didn't populate it into the database

voronianski commented 7 years ago

@Noobitious I've found a working workaround to this issue as well as for related ones. It's described here - https://github.com/vapor/mongo-driver/issues/27#issuecomment-266738711

Noobitious commented 7 years ago

@voronianski does that save the _id value into the id field in the database for you? I am unable to get it to do that. Yes, I can get the "node" to return the right field, but not populate it correctly in the database.

voronianski commented 7 years ago

@Noobitious if you use setup like this - https://github.com/voronianski/vapor-server-example/blob/master/Sources/App/Models/Post.swift then in database it will save only _id field, and id will be used by Fluent model internally. I tested it on clean database and it worked.

rafiki270 commented 7 years ago

I had this issue until I realised I have to use _id not id ... by using id without the underscore you are effectively creating a new column in the db. To have only id in your output json (for example for an API) you have to subclass makeJSON() method of your Model.

@tannernelson you might want to close this one?