Start a new topic

Unique Constraints on a collection column?

Hi



I'm building an application and looking to make the email column on the user table unique - I've looked at the Validation Rules section but there doesn't appear to be anything there to help.



Thinking I need some business logic on the onPreSave hook but can't quite get my head round it.



Am I right in thinking business logic is needed? Is there a better way? If it is business logic that's needed do you have some example code I can look at?



Any help gratefully received.



Many Thanks

Pat

Patrick,



I have not seen an official Kinvey mechanism for what you want. However, it is certainly a common need. Short of an official Kinvey solution, code like the following should do the trick in your PreSaveHook.



function onRequest(request, response, modules){



var processRequest = function() {



var collectionAccess = modules.collectionAccess;

var userCollection = collectionAccess.collection('user');



var emailQuery = { "email": request.body.email };



userCollection.findOne( emailQuery, function( error, match ) {



if( error ) {

response.body = { "error" : error.message };

response.error(400);

return;

}



if( match === null ) {

response.continue();

} else {

response.error('Email address is already in use')

}







});

}



processRequest();



}



P.S. Be careful with that. I wrote it in a custom endpoint to test it. Then, I modified it to have the correct response methods. However, I failed to change it from "onRequest" to "onPreSave". So, just use it as a guide.
Thanks for coming back to me Justin - appreciate you input.



Tried your code but couldn't get it to work I'm afraid. Changed to OnPreSave and the collection to Users rather than user, also played with the else clause of the match part but no joy.



(forgive my ignorance but I'm completely new to this language, I come from a different arena - not entirely sure what it is I'm writing(!) - think it's MongoDB query language?)



Thanks

Pat



function onPreSave(request, response, modules){



var processRequest = function() {



var collectionAccess = modules.collectionAccess;

var userCollection = collectionAccess.collection('Users');



var emailQuery = { "email": request.body.email };



userCollection.findOne( emailQuery, function( error, match ) {



if( error ) {

response.body = { "error" : error.message };

response.error(400);

return;

}



if( match === null ) {

response.continue();

} else {

response.body = { "error" : 'Email address is already in use'};

response.error(400);

return;

}







});

}



processRequest();



}
Hi Patrick,



The issue with your code is that the collection name is 'user', not 'Users. If you make that change, it should work.



Patrick,



Sorry that didn't work out. A few details:



*This is all JavaScript

*The findOne method is just JavaScript to query MongoDB

*The "Users" collection is VERY misleading. It really is just the "user" collection. I made the same mistake myself.



I've created a fake "userTest" collection on my backend. I can successfully run the code below to create this unique constraint rule. You "should" be able to just replace "userTest" with "user" and run it in your onPreSave collection hook. Notice I included a logger. You can use this to help find out what is going on. Be sure to remove it after testing. When your app takes off and you're getting 1M+ subscribers per day, you don't want to kill Kinvey with all that overhead.



function onPreSave(request, response, modules){



var logger = modules.logger;



var processRequest = function() {



var collectionAccess = modules.collectionAccess;

var userCollection = collectionAccess.collection('userTest');



var emailQuery = { "email": request.body.email };



userCollection.findOne( emailQuery, function( error, match ) {



logger.info('In findOne');

logger.info(error);

logger.info(match);



if( error ) {

response.body = { "error" : error.message };

response.error(400);

return;

}



if( match === null ) {

logger.info('Match was null');

response.continue();

} else {

logger.info('Email was already in use');

response.error('Email address is already in use')

}



});

}



processRequest();

}





If you have any trouble with it, post back. This evening I'll see how we can pair on it to solve the problem.
Justin/Michael - All sorted now and works like a charm.



I could lie but it was user error - pure and simple! I was trying to access Users collection rather than use. Then I was checking the [error].[description] rather than the [debug] message for the error so it was working I was just not seeing the error!



Sorry for wasting your time... And thanks for the info on the language being used.
Login or Signup to post a comment