Search code examples
node.jsmongodbloopbackbaasbox

Loopback ValidationError: The `Role` instance is not valid. Details: `name` already exists (value: "admin")


I'm new to loopback, however I followed the steps to install and scaffold my folder (loopback-server), inside server/boot/ I created one file script.js and included the following code:

    module.exports = function(app) {
var MongoDB = app.dataSources.MongoDB;

MongoDB.automigrate('Customer', function(err) {
   if (err) throw (err);
   var Customer = app.models.Customer;

   Customer.create([
    {username: 'admin', email: '[email protected]', password: 'abcdef'},
    {username: 'user', email: '[email protected]', password: 'abcdef'}
  ], function(err, users) {
    if (err) throw (err);
     var Role = app.models.Role;
    var RoleMapping = app.models.RoleMapping;

    //create the admin role
    Role.create({
      name: 'admin'
    }, function(err, role) {
      if (err) throw (err);
       //make admin
      role.principals.create({
        principalType: RoleMapping.USER,
        principalId: users[0].id
      }, function(err, principal) {
        if (err) throw (err);
      });
    });
  });
});

};

Now I'm getting this error:

terminal error

I commented this file out and didn't get that error. By the way, I tried to change the keys and values of {username: 'admin',..} and Role.create({name: 'admin'},.... but either doesn't work or it works but I can't login as admin.


Solution

  • If you're Role entity is being stored in a database then this code would try to create that Role entity (with a name of "admin") each time your application starts. However, after the first time, that Role would already exist, thus you get an error that you have a duplicate "name". What you might want to do is check that the Role does not already exist, or not store the Roles in your DB.

    You could add some code to check the current DB and only add that Role if it doesn't exist. Something like this:

    Role.find({ name: 'admin' }, function(err, results) {
        if (err) { /* handle this! */ }
    
        if (results.length < 1) {
            // now we know the DB doesn't have it already, so do the Role creation...
        }
    });
    

    Note that you would also want to check if that Role table already has the principals you're adding and only add them if they aren't already there.