0

I'm new to Rails and currently working on an app where my classmates/schoolmates can comment on topics/issues (relevant to us), and each of those comments should be possible to be voted up or down.

I created an own model for both the "upvote" and "downvote".

Now, in the database, I'm wondering, should there be one single integer for both vote models that can be increased, so in my controller actions it would be ... += 1. - Or should it rather be a list/collection of votes that simply is counted with the .count method to show the upvote or downvote value?

Kara
  • 6,115
  • 16
  • 50
  • 57
rails_has_elegance
  • 1,590
  • 4
  • 21
  • 37

2 Answers2

2

Rails has a feature called counter_cache for automatically counting associated models amount on their creation/destroying. Here's about it: http://guides.rubyonrails.org/association_basics.html section 4.1.2.4. It's done via extra column in DB.

jdoe
  • 15,665
  • 2
  • 46
  • 48
1

I think the option you choose depends on the requirements of your application.

  • Single Integer
    • If you don't need any other information associated with the votes, I would simply store it as a single integer in the model.
  • Record Per Vote
    • If you wanted to store additional information along with the vote, such as who and when each vote occurred, then you could create a record per vote. Then you could do a .size on the models (recommend size over count for performance reasons... or even better, use the counter_cache that jdoe pointed out).

That being said, from the description of your application, I don't think that the upvotes and downvotes necessarily need their own models. I would create an attribute for the upvotes and downvotes on your Comments model and use a single integer to represent the vote counts.

Community
  • 1
  • 1
Kelly
  • 81
  • 3
  • Thank you for your detailed answer! First I was tending to do it as a single integer for each comment, just as an extra attribute for the comment model. Then I found some voting system tutorials and they often used own models for a vote and this seemed to be a great and clean solution, as well in regard to REST resources. To be honest, after reading your post, I now more tend to the single integer way again. My app simply should collect up- and downvotes, nothing more. I want a overall upvote and downvote value, and the sorting of comments should be based upon a plusminus of up and downvotes – rails_has_elegance May 26 '12 at 23:39
  • What do you think would be the better solution in regard to REST resources and how to handle the voting mechanism in controllers? And do you think the plusminus value of each comment should be an own attribute or even model, or simply be calculated instantaneously in the controller? I'm tending more towards the extra attribute or even model way and counter_cache method, it seems to be more efficient. Sorry for so many questions! – rails_has_elegance May 26 '12 at 23:45
  • In terms of being more RESTful, then creating a separate model is the way to go. That is however, with caveat that the votes resource warrant its own model. Other voting systems have their own separate models because they [contain a lot of other features](http://www.medihack.org/2011/03/23/a-voting-extension-from-scratch-for-rails-3-part-1/). In your case, if you just need a count, you could consider it an attribute of the Comments resource. If you want anything more (validations, error handling, logging), then I would go with a separate model. – Kelly May 27 '12 at 19:40
  • As for where to handle the plus/minus, that belongs in the Models (it's in charge of manipulating the data; this also conforms to [Fat Model, Skinny Controller](http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model)). Hope this helps! – Kelly May 27 '12 at 19:41
  • Thank you very much for all your help! I think I'm gonna go the model way, since I think I want vote restriction to one vote every 24 hours and it might be possible that I later want to add those features you were talking about. – rails_has_elegance May 28 '12 at 00:30