0

So I've run into this issue before but now I really want to flatten it out and never run into it again. I have a user schema which accepts other users as friends.

However, instead of just adding a 'friends' key to the User schema with a single object of type: Schema.Types.ObjectId, ref: "User" , I want to include other properties such as friendship status, etc. Check the code below.

    UserSchema = new Schema({
  email: {
    type: String,
    unique: true
  },
  name: {
    type: String,
    min: [1, "Name must be at least 1 character in length"],
    max: [18, "Name cannot exceed 18 characters in length"]
  },
  password: {
    type: String,
    min: [6, "Password must be at least 6 characters in length"],
    max: [18, "Password cannot exceed 18 characters in length"]
  },
  friendships: [
    {
      friend: {
        type: Schema.Types.ObjectId,
         ref: "User"
       },
       myGain: {
         type: Number,
         default: 0
       },
       myDebt: {
         type: Number,
          default: 0
        },
        status: {
          type: String,
          default: "pending"
        },
        requestor: {
          type: Number
        }
      }
    ]
});

As you can see, friendships are now an array, with each object containing five properties, the first being 'FRIEND'. This is the actual reference to the User model, which will contain another user.

My issue is it starts to confuse me when doing things like adding a friend.

In my controller, here is how I am creating a friendship.

const friendshipController = {
  create: function(req, res) {
    User.findByIdAndUpdate(req.params.id,
    { $push: { "friendships": {"friend": req.params.friendId } } }, {upsert: true}, function(err, user) {
      if (err) {
        console.log(err);
      } else {
        User.findByIdAndUpdate(req.params.friendId,
          { $push: { "friendships": {"friend": req.params.id } } }, {upsert: true}, function(err, user) {
            if (err) {
              console.log(err);
            } else {
              console.log("donezo");
            }
          }
        )
      }
    } )
  }
}

The problem is when I look at the new records in mongo, it is the following:

password" : "password",
    "bets" : [ ],
    "friendships" : [
        {
            "friend" : ObjectId("581676fbfbbb9a43ac8c979d"),
            "_id" : ObjectId("58168257a7c4cb4512b1cafb"),
            "status" : "pending",
            "myDebt" : 0,
            "myGain" : 0
        }
    ],
    "__v" : 0

What is that extra _id value underneath friend? What is that referring to? It is a unique value in that when I look at the other friend who had the friendship created, that ObjectId value is a little bit different. The actual ObjectId value of the "friend" property is the only one I want. That is the correct value. That value (ending in 979d) is referencing the other friend. I just don't get what that other _id value is.

Thanks

Community
  • 1
  • 1
user7024499
  • 951
  • 1
  • 10
  • 24
  • 1
    Possible duplicate of [Stop Mongoose from creating \_id property for sub-document array items](http://stackoverflow.com/questions/17254008/stop-mongoose-from-creating-id-property-for-sub-document-array-items) – Bertrand Martel Oct 30 '16 at 23:38
  • Thanks for that link resource. I looked it over and it's not a duplicate of this question. Similar and having to do with schema's and _id's but not a duplicate. Good resource though. My question is what is this _id referring to? Did mongoose literally just implicitly assign that as a friendship ID? Because that would be really helpful for me if I need to change the friendship status from my front end, I can just pass that _id through and update a specific friendship. Should make querying all my friendships easier, i.e. findAndUpdateOne where _id = .. you get the idea. Is that what that _id is? – user7024499 Oct 31 '16 at 00:23
  • I think you could do` findOne({"frendships._id" : [The objectId]})` for all the objects in the array.The Id gets assigned automatically when you push to the array. It is a common thing – jack blank Oct 31 '16 at 01:48

1 Answers1

1

Yes, Mongoose assigns an ObjectID to each subdocument you are creating unless you tell it not to. As you say, it "literally just implicitly assigns" it. It's a unique value assigned to that one relationship object you saved.

Paul
  • 35,689
  • 11
  • 93
  • 122