A more elegant way to handle role-based collection-getting?


#1

I am having a bit of trouble creating a schema where it will have to grab another schema from another collection. Sometimes the schemas will be inherently different. For example, here is my user schema

UserSchema = new SimpleSchema({
  // ...
  settings: {
    type: Object
  },
  "settings._id": {
    type: String,
    optional: true,
    allowedValues: function () {
      var collection = this.field('settings.collection');
      if(collection.isSet) {
        return Mongo.Collection.get(collection.value).find().map(function(doc) {
          return doc._id;
        })
      } else {
        return null;
      }
    }
  },
  "settings.collection": {
    type: String,
    autoValue: function () {
      var role = this.field('role');
      if(role.isSet) {
        switch(role.value) {
          case 'user': return 'user_settings';
          case 'admin': return 'admin_settings';
          default: return null;
        }
      }
    }
  },
  role: {
    type: String,
    allowedValues: function () {
      return ['user', 'admin'];
    }
  }
});

Meteor.users.helpers({
  getSettings: function () {
    var collection = Mongo.Collection.get(this.settings.collection);
    return collection.findOne(this.settings._id);
  }
});

So essentially, I have a role-based switch to get a different settings schema for each user in a role. Eg, on fetching different types of users:

> Meteor.users.findOne({role: "user"}).getSettings();
{
  "sendEmailUpdates": false,
  "denyGameRequests": true
}
Meteor.users.findOne({role: "admin"}).getSettings();
{
  "contact": {
    "email": "email@email.org",
    "phoneNumber": "111-111-1111"
  },
  "showThumbnail": true
}

Is there any more elegant way to do this? I feel like my solution is bad.