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

findByIdAndUpdate doesnt validate required paths even if runValidators is true, not suitable for PUT #3263

Open
gregorianrants opened this issue Nov 9, 2023 · 0 comments

Comments

@gregorianrants
Copy link
Contributor

gregorianrants commented Nov 9, 2023

The Issue

I have raised this issue before on discord, and i think some things were modified but i still think there are problems with using

findByIdAndUpdate for a put request.

even when you use {runValidators: true}

it still only runs validation on the paths we supply to it.
a put request should replace a document with the data provided.
however if we dont provide a value for a required path in the update, it wont run the required validator on the path that has no value. Only the paths provided will be replaced and the path that wasnt supplied will still have its previous value.

as pointed out in the mongoose docs

https://mongoosejs.com/docs/validation.html#update-validators

it also says in the mongoose docs

"The save() function is generally the right way to update a document with Mongoose. With save(), you get full validation and middleware."

https://mongoosejs.com/docs/documents.html#updating-using-queries

An example

if i have the model

const blogSchema = new mongoose.Schema({
  title: { type: String, required: true },
  author: String,
  url: { type: String, required: true },
  likes: { type: Number, default: 0 },
})

where title is required

and my controller is as such

router.put('/:id', async (req, res) => {
  const { title, author, url, likes } = req.body
  const id = req.params.id
  const updateData = { author, url, likes, title }
  const updatedBlog = await BlogModel.findByIdAndUpdate(id, updateData, {
    runValidators: true,
    new: true,
    context: 'query',
  })
  res.status(200).json(updatedBlog)
})

and my blog looks like so before the update

{
    "title": "lotr",
     "author": "jrr tolkien",
     "url": "www.rivendale",
     "likes": "1000000"
}

and i send the following data through a put request, with no title.

{
     "author": "jrr hartley",
     "url": "www.flyfishing",
     "likes": "1000000"
}

afterwards my data will be like so

{
    "title": "lotr",
     "author": "jrr hartley",
     "url": "www.flyfishing",
     "likes": "1000000"
}

and jrr hartley didnt write lord of the rings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant