I'm new to Meteor, building my first app. It's a cocktail-recipe app, with a collection of drinks and a collection of ingredients.
Each drink can have many ingredients. For each ingredient in a drink, there will be a quantity (number) and a unit of measure (string).
I vaguely suspect that, for this use case, something like the publish-with-relations package may be overkill, but I'm not clear on the best way to create and populate the third collection that would house this relationship between drinks and ingredients.
Here's what my drinks collection looks like:
Drinks = new Mongo.Collection('drinks');
Drinks.allow({
update: function(userId, drink) { return ownsDocument(userId, drink); },
remove: function(userId, drink) { return ownsDocument(userId, drink); }
});
Drinks.deny({
update: function(userId, drink, fieldNames) {
//only allow editing these fields:
return (_.without(fieldNames, 'drinkName', 'drinkIngredients').length > 0);
}
});
Meteor.methods({
drinkInsert: function(drinkAttributes) {
check(Meteor.userId(), String);
check(drinkAttributes, {
drinkName: String,
drinkIngredients: Array,
drinkDescription: String,
drinkInstructions: String
});
var errors = validateDrink(drinkAttributes);
if (errors.drinkName || errors.drinkIngredients)
throw new Meteor.Error('invalid-drink', "You must enter a drink name and ingredients.");
var drinkWithSameName = Drinks.findOne({drinkName: drinkAttributes.drinkName});
if (drinkWithSameName) {
return {
drinkExists: true,
_id: drinkWithSameName._id
}
}
var user = Meteor.user();
var drink = _.extend(drinkAttributes, {
userId: user._id,
author: user.username,
submitted: new Date(),
commentsCount: 0,
upvoters: [],
votes: 0
});
var drinkId = Drinks.insert(drink);
return {
_id: drinkId
};
},
upvote: function(drinkId) {
check(this.userId, String);
check(drinkId, String);
var affected = Drinks.update({
_id: drinkId,
upvoters: {$ne: this.userId}
}, {
$addToSet: {upvoters: this.userId},
$inc: {votes: 1}
});
if (! affected)
throw new Meteor.Error('invalid', "Vote not counted.");
}
});
validateDrink = function (drink) {
var errors = {};
if (!drink.drinkName)
errors.drinkName = "Please name your drink.";
if (!drink.drinkIngredients)
errors.drinkIngredients = "Please add some ingredients.";
if (!drink.drinkDescription)
errors.drinkDescription = "Please write a brief description of your drink.";
if (!drink.drinkInstructions)
errors.drinkInstructions = "Please include step-by-step instructions for mixing this drink.";
return errors;
}
Here's my ingredients collection:
Ingredients = new Mongo.Collection('ingredients');
Meteor.methods({
ingredientInsert: function(ingredientAttributes) {
check(this.userId, String);
check(ingredientAttributes, {
ingredientName: String
});
var user = Meteor.user();
ingredient = _.extend(ingredientAttributes, {
userId: user._id,
author: user.username,
submitted: new Date()
});
//create the ingredient, save the id
ingredient._id = Ingredients.insert(ingredient);
return ingredient._id;
}
});
My thinking is that the relationship should live in a collection called drinkIngredients, but I'm not clear on the best way to set up that collection in Meteor. I'd appreciate some guidance on this. Or, if I'm just making things harder on myself by not just using publish-with-relations, please let me know.
Thanks very much.