Is there any way to require only one (or more than one, but not all) of several columns in a single collection in Mongoose.js? In my case, I am using Passport and want my user to sign up via one of the providers I provide, or make his/her own. However, I do not want to require the user to sign up via any one provider, but rather whichever one he/she wishes.
Here is a sample schema, from the scotch.io
tutorial on Passport (NOTE: This is an example. I am not going to use it in my app, but may use something like it):
// app/models/user.js
// load the things we need
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
// define the schema for our user model
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
How do I make it required that at least one of the objects local
, facebook
, twitter
, or google
is specified (not null
, not undefined
, etc.) before saving the document, without making any single one required (and the other ones not required) or making all of them required? In terms of the app, this would make the user be required to sign up for the first time via a username & password; a Twitter or Facebook OAuth account, or a Google+ OpenID account. However, the user would not be tied to any one provider, so he/she would not have to sign up via a username & password, but nor would he/she have to sign up via a social networking account if that's not his/her thing.