railsbridge/docs — pull request #280 by tjgrathwell (2013-11-24 23:32:34+00:00)
Title: Suggestotron: Implement voting as a custom action on the topics controller

Hello RailsBridgists. This commit might be somewhat controversial so I am doing it as a PR to get feedback.

Currently in Suggestotron voting is done as its own model, which is a little excessive on the surface because it could just be a votes_count column on each topic. But it's helpful that it teaches students a little about associations and allows future expansion of the app (where every vote could have a user_id, enforcing that each user gets only get one vote).

My problem is with how voting is implemented as votes#create, which doesn't provide a good option for a symmetrical 'downvote' action -- downvoting means you have to do a 'destroy' on **some particular vote for this topic**, which is a little goofed. Additionally, we're sending along the `topic_id` when creating the upvote link, which Rails just uses as another query parameter rather than it being part of the route.

As I see it, there's a couple of options to make this more idiomatic and clear:

1. Make 'votes' a nested resource of 'topics', so that the upvote link is topic_votes_path(topic) (POST). This removes the 'topic_id' problem but doesn't make creating downvotes any easier. A downvote link would still need to be crafted as topic_vote_path(topic, topic.votes.first) (DESTROY), or a custom topic_votes_path(topic) (DESTROY) could be created.
1. Make voting an 'upvote' action on topics, so that the upvote link is upvote_topic_path(topic) (POST). This makes crafting a downvote action as easy as making downvote_topic_path, which is free to find a vote and destroy it without the view layer caring at all about that process. It also has the benefit of teaching students a little more about how to create a route using something other than `resources :model_name`.

The only argument I forsee against the second option is from RESTaholics who think everything ought to be one of the standard CRUD actions whenever possible. But I don't know how common that notion is or what other people feel about the issue. SO: comment, please!