$exists operator does not work on mongoose document
See original GitHub issueDescribe the bug
{ $exists: boolean }
operator does not work on mongoose document. With the same ability and a plain object it works fine.
To Reproduce
package.json
{
"name": "example",
"main": "index.js",
"scripts": {
"start": "node src/index.js"
},
"dependencies": {
"@casl/ability": "^6.1.1",
"mongoose": "^6.6.0"
}
}
src/Post.js
const mongoose = require("mongoose");
const Post = new mongoose.Schema({
title: String,
author: String,
});
module.exports = mongoose.model("Post", Post);
src/defineAbility.js
const { defineAbility } = require("@casl/ability");
module.exports = defineAbility((can, cannot) => {
can("manage", "Post", {
author: { $exists: true },
});
});
src/index.js
const ability = require("./defineAbility");
const subject = require("@casl/ability").subject;
const PostModel = require("./models/Post.js");
const draftPost = new PostModel({ title: "Lorem Draft" });
const myPost = new PostModel({
title: "Lorem Ipsum",
author: "Max Mustermann",
});
console.log("With mongoose");
console.log("can read draftPost", ability.can("read", draftPost)); // expected: false -> result: false
console.log("can read myPost", ability.can("read", myPost)); // expected: true -> result: false
console.log("With plain object");
console.log(
"can read draftPost",
ability.can("read", subject("Post", draftPost.toObject())) // expected: false -> result: false
);
console.log(
"can read myPost",
ability.can("read", subject("Post", myPost.toObject())) // expected: true -> result: true
);
Output
With mongoose
can read draftPost false
can read myPost false
With plain object
can read draftPost false
can read myPost true
Expected behavior
Supports $exists
operator on mongoose documents.
CASL Version
@casl/ability
- v6.1.1
Environment:
Node.js
- v16.17.0
Issue Analytics
- State:
- Created a year ago
- Comments:7 (5 by maintainers)
Top Results From Across the Web
Find all docs where field doesn't exists, plus if field exists ...
In the stackoverflow collection, this will find all documents that do not have the howmuch field plus all documents that do have howmuch...
Read more >[Solved]-Mongoose {$exists: false} not working, why?-mongodb
It occurs with all Default value'd fields, mongoose just automatically sets these values to their defaulted value on the return call (if you...
Read more >$exists — MongoDB Manual
MongoDB $exists does not correspond to SQL operator exists . For SQL exists , refer to the $in operator. Tip ...
Read more >The mongoose exists function - ObjectRocket
The exists() method returns a boolean value, i.e. either true or false. This method checks if a particular document exists in a collection...
Read more >Mongoose v6.8.2: Schemas
In these cases, Mongoose only creates actual schema paths for leaves in the tree. (like meta.votes and meta.favs above), and the branches do...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
OK, by looking into mongoose I see that it defines properties on model prototype. So,
And this is how
$exists
checks the existence -> https://github.com/stalniy/ucast/blob/master/packages/js/src/interpreters.ts#L70 . It requires property to be defined on the object itself.Looking at sift.js it also uses
hasOwnProperty
but mingo.js gets the actual property.Based on Mongo docs:
So, it’s hard to judge whether
document contain the field
should be true if the field is actually in its prototype.In your case, I think better to check based on empty string or write your own
$exists
that will work according to your expectations (i.e., checks whether property in object or its prototype chain). Check this guide for further details -> https://casl.js.org/v6/en/advanced/customize-abilitythat’s why
$exists
for mongoose documents always returnsfalse