MonkeyBonkey
MonkeyBonkey

Reputation: 47901

how to implement the likes post pattern in parse

Given the standard use case of a user is able to like a post.

And Using the parse example

var user = Parse.User.current();
var relation = user.relation("likes");
relation.add(post);
user.save();

What's the best way to keep a count of total likes per post? Should I:

  1. increment a total likes counter on the post object with a beforeSave cloud code hook on User that looks for obj.isDirty("likes") and then figures out which object was added somehow (I'm not sure to find which post was added in this case)

  2. create a separate likes object in parse and do count queries against it (probably not because parse recommends against doing count queries)

  3. increment the likes counter on product client-side at the same time the user is adding post to their users relation (security issue and synchronization issue?)

Upvotes: 3

Views: 419

Answers (1)

danh
danh

Reputation: 62676

Its a really good, thoughtful question. Looking at your ideas:

  1. Seems natural to put a likes counter on post, and natural to maintain it on beforeSave of user. But you're also right that the dirty info (as far as I know) doesn't tell you enough about which to-many side of the relation is new. I'd exclude this otherwise fine idea because of this.

  2. Also reasonable to consider a "join table", and I believe is what parse is doing for you anyway with the to-many relation. The benefit is you can use it for count query. I was unaware that parse recommends against doing count queries. You'd have to maintain this table, and it would be an extra step from users to posts or posts to users, but I think this is workable.

  3. Nothing wrong with just having the client do the increment on post. But you're right again that this means you'll be permitting clients to write to posts not their own, so the posts' ACL will have to be weaker. I wouldn't worry much about synch... if we needed moonshot precision on timing for liking posts and counting likes, we would design something else entirely, probably without parse.com.

I think I'd go with idea (4). Which is idea (3) run in a cloud function. (Which is really a manual form of beforeSave, which is basically idea (1)).

Parse.Cloud.define("userLikesPost", function(request, response) {
    // so we can leave posts ACL restricted to the creator
    Parse.Cloud.useMasterKey();
    var post;
    var postId = request.params.postId;
    var query = new Parse.Query("Post");
    query.get(postId).then(function(result) {
        post = result;
        post.increment("likeCount", 1);
        return post.save();
    }).then(function() {
        var user = request.user;
        user.add("likes", post);
        return user.save();
    }).then(function(result) {
        response.success(result);
    }, function(error) {
        response.error(error);
    });
});

Upvotes: 2

Related Questions