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

Mongoose not saving nested documents #12398

Closed
2 tasks done
jamesbruice opened this issue Sep 5, 2022 · 5 comments · Fixed by #12521
Closed
2 tasks done

Mongoose not saving nested documents #12398

jamesbruice opened this issue Sep 5, 2022 · 5 comments · Fixed by #12521
Assignees
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation
Milestone

Comments

@jamesbruice
Copy link

jamesbruice commented Sep 5, 2022

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

5.12.14

Node.js version

v16.13.1

MongoDB server version

5.0.11

Description

When modifying a field on a populated document, changes should be saved, when saving the parent.

This is not occ, instead I need to save the document myself (see Steps to Reproduce)

Steps to Reproduce

Schemas

const boardSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    tasks: [
        {
            type: Schema.Types.ObjectId,
            ref: 'Task'
        }
    ]
})
const taskSchema = new mongoose.Schema({
    name: {
        type: String
    },
    description: String
})

route to change name

router.patch('/:boardId/:taskId', async (req, res) => {
    const { boardId, taskId } = req.params
    const { value } = req.body
    const board = await Board.findById(boardId).populate('tasks')

    board.tasks.find(x => x._id.toString() === taskId).name = value

    //await board.tasks[0].save() // <--------- Saving changes to task[0] // THIS SHOULD NOT BE REQUIRED
    await board.save() // <-------------------- Not saving changes to nested tasks (e.g. the name)
    res.json(board) // <----------------------- Showing correct change
    res.send('OK')
})

Expected Behavior

image
https://mongoosejs.com/docs/subdocs.html#subdocuments

Saving the tasks individually should not be required. They should be saved when the parent is being saved

@IslandRhythms IslandRhythms added help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary and removed help This issue can likely be resolved in GitHub issues. No bug fixes, features, or docs necessary labels Sep 7, 2022
@IslandRhythms IslandRhythms self-assigned this Sep 7, 2022
@IslandRhythms IslandRhythms added docs This issue is due to a mistake or omission in the mongoosejs.com documentation confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed docs This issue is due to a mistake or omission in the mongoosejs.com documentation labels Sep 12, 2022
@IslandRhythms
Copy link
Collaborator

const mongoose = require('mongoose');


const aSchema = new mongoose.Schema({
  name: String
});

const bSchema = new mongoose.Schema({
  persons: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'A'
  }]
});

const A = mongoose.model('A', aSchema);
const B = mongoose.model('B', bSchema);


async function run() {
  await mongoose.connect('mongodb://localhost:27017');
  await mongoose.connection.dropDatabase();

  const person1 = await A.create({ name: 'Test Testerson' });
  const person2 = await A.create({ name: 'Test' });
  const id = person2._id;

  await B.create({ persons: [person1._id, person2._id] });

  const test = await B.findOne().populate('persons');
  console.log(test);
  test.persons.find(x => x._id.toString() === id.toString()).name = 'Value Changed';
  await test.save();
  // await test.persons[0].save();
  // await test.persons[1].save();
  const res = await B.findOne().populate('persons');
  console.log(res);
}

run();

@IslandRhythms IslandRhythms added docs This issue is due to a mistake or omission in the mongoosejs.com documentation and removed confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. labels Sep 12, 2022
@IslandRhythms
Copy link
Collaborator

Populated docs are different from subdocs. If you set a populated value, you need to call save on the doc.

@jamesbruice
Copy link
Author

Could you explain the difference between a ref and a subdocument? @IslandRhythms

@IslandRhythms
Copy link
Collaborator

A ref indicates what Model populate should look at when querying the indicated path. A subdocument is described in the image you attached to this issue.

@vkarpov15
Copy link
Collaborator

@jamesbruice when you populate a ref, you get a populated document, which is a distinct top-level document, rather than a subdocument embedded in your document. The difference is that an embedded subdocument is stored in MongoDB as a subdocument, rather than as an ObjectId that refers to another document.

@vkarpov15 vkarpov15 modified the milestones: 6.6.4, 6.6.5 Sep 30, 2022
vkarpov15 added a commit that referenced this issue Oct 5, 2022
docs(subdocs): clarify that populated docs are not subdocs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs This issue is due to a mistake or omission in the mongoosejs.com documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants