5
votes

So, I have just started a meteor project and have included the accounts-password package. The package only supports few keys. I want to add a new SimpleSchema to the users collection with some more fields.

I am not given to create another instance of users collection with

@users = Mongo.Collection('users');
//Error: A method named '/users/insert' is already defined

I can attach a schema but will be forced to keep alot of fields optional, and may not be able to register with the default package otherwise.

Can I add simpleSchema without making other fields optional and still be able to login properly?

Or is there any other work around for this case?

Thank you for help in advance

2

2 Answers

-1
votes

You can get users collection with:

@users = Meteor.users;

You can find nice example of defining user collection in the docs of collection2 package: https://atmospherejs.com/aldeed/collection2

Schema = {};
Schema.User = new SimpleSchema({
    username: {
        type: String,
        regEx: /^[a-z0-9A-Z_]{3,15}$/
    },
    emails: {
        type: [Object],
        // this must be optional if you also use other login services like facebook,
        // but if you use only accounts-password, then it can be required
        optional: true
    },
    "emails.$.address": {
        type: String,
        regEx: SimpleSchema.RegEx.Email
    },
    "emails.$.verified": {
        type: Boolean
    },
    createdAt: {
        type: Date
    },
    profile: {
        type: Schema.UserProfile,
        optional: true
    },
    services: {
        type: Object,
        optional: true,
        blackbox: true
    },
    // Add `roles` to your schema if you use the meteor-roles package.
    // Option 1: Object type
    // If you specify that type as Object, you must also specify the
    // `Roles.GLOBAL_GROUP` group whenever you add a user to a role.
    // Example:
    // Roles.addUsersToRoles(userId, ["admin"], Roles.GLOBAL_GROUP);
    // You can't mix and match adding with and without a group since
    // you will fail validation in some cases.
    roles: {
        type: Object,
        optional: true,
        blackbox: true
    },
    // Option 2: [String] type
    // If you are sure you will never need to use role groups, then
    // you can specify [String] as the type
    roles: {
        type: [String],
        optional: true
    }
});
-2
votes

You have three ways to adapt for the attach of a schema to such a collection:

  • Make every new field optional.
  • Have default values (friends defaults to [] for example).
  • Update the UI to include new mandatory elements (a radio for "P = NP" or "P != NP").

Each option is somewhat valid in itself. Chose what seems the most logical in the current context and what will give you the least headaches.

Do you absolutely need a user-given value for someField when he registers? Then you have to update the UI to fetch this value.
Is the presence of someField important, and it can be initialized to a default object (an empty array, null, 0...)? Then a default value will fit, and it will be added when Collection2 cleans the document.
None of the above? Optional.


As a somewhat personal note, I prefer this kind of code:

someUser.friends.forEach(sendGifts);

To this kind:

if(someUser.hasOwnProperty('friends')) {//Or _.has(someUser, 'friends') but it sounds sad
  someUser.friends.forEach(sendGifts);
}

In the second code friends is an optional field, so we're not sure if it's present or undefined. Calling forEach on undefined results in a nice big error, so we have to check for the field existence first... Thus, I would advise slightly avoiding optional fields for consistency and simplicity.