posts.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Not a "var", to make it global.
  2. Posts = new Mongo.Collection('posts');
  3. Posts.allow({
  4. update: function (userId, post) {
  5. return ownsDocument(userId, post);
  6. },
  7. remove: function (userId, post) {
  8. return ownsDocument(userId, post);
  9. }
  10. });
  11. Posts.deny({
  12. update: function (userId, post, fieldNames) {
  13. // _.without() is like PHP array_diff($source, ...$keys).
  14. // May only edit the following two fields:
  15. return (_.without(fieldNames, "url", "title").length > 0);
  16. }
  17. });
  18. Posts.deny({
  19. // In a post edit, the update is performed by a $set modifier, with the same
  20. // fields as the base inserted post: url and title, so we can pass it to
  21. // the post validator as it currently stands.
  22. update: function (userId, post, fieldNames, modifier) {
  23. var errors = validatePost(modifier.$set);
  24. return errors.title || errors.url;
  25. }
  26. });
  27. validatePost = function (post) {
  28. var errors = {};
  29. if (!post.title) {
  30. errors.title = "Please fill in a headline";
  31. }
  32. if (!post.url) {
  33. errors.url = "Please fill in a URL";
  34. }
  35. return errors;
  36. };
  37. // This is in lib/ instead of server/ for latency compensation.
  38. Meteor.methods({
  39. postInsert: function(postAttributes) {
  40. "use strict";
  41. check(this.userId, String); // Or Meteor.userId() ?
  42. check(postAttributes, {
  43. title: String,
  44. url: String
  45. });
  46. var errors = validatePost(postAttributes);
  47. if (errors.title || errors.url) {
  48. throw new Meteor.Error('invalid-post',
  49. "You must set a title and URL for your post");
  50. }
  51. var postWithSameLink = Posts.findOne({ url: postAttributes.url });
  52. if (postWithSameLink) {
  53. // Return to skip the insert.
  54. return {
  55. postExists: true,
  56. _id: postWithSameLink._id
  57. };
  58. }
  59. var user = Meteor.user();
  60. var post = _.extend(postAttributes, {
  61. userId: user._id,
  62. author: user.username,
  63. submitted: new Date(),
  64. commentsCount: 0,
  65. upvoters: [],
  66. votes: 0
  67. });
  68. var postId = Posts.insert(post);
  69. return {
  70. _id: postId
  71. };
  72. },
  73. upvote: function (postId) {
  74. check(this.userId, Match.OneOf(null, String));
  75. check(postId, String);
  76. if (this.userId === null) {
  77. throw new Meteor.Error('invalid', 'Not logged in');
  78. }
  79. var affected = Posts.update({
  80. _id: postId,
  81. upvoters: { $ne: this.userId }
  82. }, {
  83. $addToSet: { upvoters: this.userId },
  84. $inc: { votes: 1 }
  85. });
  86. if (!affected) {
  87. throw new Meteor.Error('invalid', "You weren't able to upvote that post");
  88. }
  89. }
  90. });