export const renameMeal = new ValidatedMethod({ name: 'meal.rename', validate: new SimpleSchema({ mealId: { type: String }, name: { type: String } }).validator(), run({ mealId, name }) { if (!this.userId) { throw new Meteor.Error('unauthorized', 'You must be logged in to remove a meal.'); } else if (!Meals.findOne({ _id: mealId, userId: this.userId})) { throw new Meteor.Error('notfound', 'The meal specified was not found for this user.'); } Meals.update(mealId, { $set: { name: name }}); } });
Other frameworks handle this kind of thing by providing a way to execute logic across multiple server actions (for example, ActionFilters in ASP.NET MVC). Meteor has something similar as part of its ValidatedMethod package, they are called 'mixins'. They provide a way for users to chain the run() function of the method. For example:
export const authenticated = createMixin(function() { if (!this.userId) { throw new Meteor.Error('unauthorized', 'You must be logged in to access this method.'); }; });
The 'createMixin' is a helper method that adds a new function into the chain of run() functions. In my opinion the platform should have provided something like this out of the box, here is my implementation:
function createMixin(callback) { var myMixin = function(methodOptions) { const runFunc = methodOptions.run; methodOptions.run = function() { callback.call(this, ...arguments); runFunc.call(this, ...arguments); } return methodOptions; } return myMixin; }
With this in place, validated methods can be re-written to use the mixins:
export const renameMeal = new ValidatedMethod({ name: 'meal.rename', validate: new SimpleSchema({ mealId: { type: String }, name: { type: String } }).validator(), mixins: [Mixins.authenticated, Mixins.mealOwner], run({ mealId, name }) { Meals.update(mealId, { $set: { name: name }}); } });
You can check the code up to this point by using this commit or visit the live demo.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.