1

I'm thinking of developing an app that will have an up vote/ down vote system (like we have here in Stack Overflow). I'm having a hard time building the base - meaning the architecture.

Lets say I have a list with posts, viewed in a ListView and the data comes from a database (Parse.com db). Each post will have it's own Int column named "votes" containing the amount of up-votes/down-votes it has.

And here is my problem: Absolutely I want every user to be able to up-vote only once to each post. How do I do that? How do I save each user in the database so he could vote only once?

EladB
  • 326
  • 5
  • 15
  • If don't want to users to up/down-vote twice that means that a simple int for keeping the numbers is not enough. You will have to associate each individual user with the votes on the post. So users and posts would be connected with another table/relation to keep track of the votes. – Panickos Neophytou Feb 01 '15 at 22:11
  • Exactly. that is the part I'm having trouble understanding. Do I need each user to point to each row in my Posts table? Or maybe save the each post ID he liked? that means that as time passes each user file will be very heavy, won't they? – EladB Feb 02 '15 at 12:13

2 Answers2

1

If you are going to solve the problem in database design level, something like this may help you:
enter image description here

Primary key of USER {USER_ID}
Primary key of POST {USER_ID , POST_SEQUENCE_NUMBER}
Primary key of Vote {VOTE_ID}

Now having the unique constraint
vote_table_uc1 = {voter_FK, post_FK}
will satisfy

every user to be able to up-vote only once to each post

In the mean time having this unique constraint
vote_table_uc2 = {voter_FK != post_FK.USER_ID}
will satisfy

You can not vote you own post

Mohsen Heydari
  • 7,256
  • 4
  • 31
  • 46
  • Hey Moshen. Thanks, but I'm having a hard time understanding this. – EladB Feb 02 '15 at 12:16
  • Hi, the model or the constraints are understandable? – Mohsen Heydari Feb 02 '15 at 12:40
  • The models I understand. I did something of sorts. It's the constraints I don't understand. I found this question http://stackoverflow.com/questions/7487476/facebook-like-data-structure And I'm guessing you're suggestion is pretty similar. It basically means: create 3 tables: User, Post and Like. User and Post have IDs and Like has a pointer to the User row and to Post row. – EladB Feb 02 '15 at 16:48
1

As you note in your question you are using Parse.com. I haven't used Parse.com before, so what I'm suggesting may not work right out of the box, but a quick search in the documentation directed me to this link: https://parse.com/docs/relations_guide#manytomany-jointables

Join-tables allow you have many-to-many relations with information attached to the relation (e.g. vote (-1/+1), date, etc.)

What you need here are 2 entities (Post and User) which should be connected using a join-table Vote that keeps track of the votes of each user towards that post. I would try something like this:

ParseUser currentUser = getCurrentUser();
ParseObject post = ...  //This is the post where the user is going to vote on.

ParseObject currentVote = new ParseObject("Vote");
currentVote.put("voter", currentUser);
currentVote.put("post", post);
currentVote.put("date", new Date());
currentVote.put("vote", -1); //down-vote
currentVote.saveInBackground();

You can see where this is going.

I'm not sure how Parse.com handles constraints, but based on the query interface you may want to ensure that a user is only voting once on each post by running a query before adding the vote:

// set up the query on the Vote table
ParseQuery<ParseObject> query = ParseQuery.getQuery("Vote");
query.whereEqualTo("voter", ParseUser.getCurrentUser());
query.whereEqualTo("post", post);

// execute the query
query.findInBackground(newFindCallback<ParseObject>() {
    public void done(List<ParseObject> votes, ParseException e) {
        if(votes.length <= 0) {
            //apply the vote as above
        } else {
            //user already voted
        }
    }
});

Hope this helps.