|
| 1 | +# Allow People To Vote |
| 2 | + |
| 3 | +## Goals |
| 4 | +Now we're going to add a button people can click to cast a vote. |
| 5 | + |
| 6 | +## Steps |
| 7 | +### Step 1: Add a new controller action for voting |
| 8 | +Edit `app/controllers/topics_controller.rb` and add this method at the end of the controller, above the `private` keyword: |
| 9 | + |
| 10 | +```ruby |
| 11 | +def upvote |
| 12 | + @topic = Topic.find(params[:id]) |
| 13 | + @topic.votes.create |
| 14 | + redirect_to(topics_path) |
| 15 | +end |
| 16 | +``` |
| 17 | + |
| 18 | +* `@topic = Topic.find(params[:id])` finds the topic in the database with that id and stores it in the variable @topic. |
| 19 | +* `@topic.votes.create` creates a new vote for the current topic and saves it in the database. |
| 20 | +* `redirect_to(topics_path)` tells the browser to go back to `topics_path` (the topics list). |
| 21 | + |
| 22 | +### Step 2: Add a new route for voting |
| 23 | +Open `config/routes.rb` and find the section that looks like this: |
| 24 | + |
| 25 | +```ruby |
| 26 | +resources :topics |
| 27 | +``` |
| 28 | + |
| 29 | +Replace that line so it looks like this: |
| 30 | + |
| 31 | +```ruby |
| 32 | +resources :topics do |
| 33 | + member do |
| 34 | + post 'upvote' |
| 35 | + end |
| 36 | +end |
| 37 | +``` |
| 38 | + |
| 39 | +Verify that upvote route was added successfully by checking the output of `rake routes`. You should see a line that looks like this: |
| 40 | + |
| 41 | +```bash |
| 42 | + Prefix Verb URI Pattern Controller#Action |
| 43 | +upvote_topic POST /topics/:id/upvote(.:format) topics#upvote |
| 44 | +``` |
| 45 | +### Step 3: Add the button to the view |
| 46 | +Edit app/views/topics/index.html.erb so that the bottom loop looks like this: |
| 47 | + |
| 48 | +```ruby |
| 49 | +<% @topics.each do |topic| %> |
| 50 | + <tr> |
| 51 | + <td><%= topic.title %></td> |
| 52 | + <td><%= topic.description %></td> |
| 53 | + <td><%= pluralize(topic.votes.count, "vote") %></td> |
| 54 | + <td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td> |
| 55 | + <td><%= link_to 'Show', topic %></td> |
| 56 | + <td><%= link_to 'Edit', edit_topic_path(topic) %></td> |
| 57 | + <td><%= link_to 'Destroy', topic, method: :delete, data: { confirm: 'Are you sure?' } %></td> |
| 58 | + </tr> |
| 59 | +<% end %> |
| 60 | +``` |
| 61 | +
|
| 62 | +* `pluralize(topic.votes.count, "vote")` displays the number of votes the topic has, plus the word "vote" or "votes" accordingly. |
| 63 | +* `button_to '+1'` creates an HTML button with the text "+1". |
| 64 | +* `upvote_topic_path(topic)` creates the appropriate URL for the action we want to invoke. In this case, we want to upvote the current topic. |
| 65 | + * `upvote_topic_path(topic)` would return `/topics/42/upvote` (if topic.id was 42) |
| 66 | +* `method: :post` ensures we do the create action of CRUD, not the read action. |
| 67 | +
|
| 68 | +### Step 4: Confirm your changes in the browser |
| 69 | +Go back to and refrest the app in the otherweb browser and try out the latest changes. |
| 70 | +
|
| 71 | +Revel in the fact that you didn't have to restart the server to see these changes. Hawt, no? |
| 72 | +
|
| 73 | +Next Step: |
| 74 | +Go on to [Redirect To The Topics List After Creating A New Topic](redirect_to_the_topics_list_after_creating_a_new_topic.md) |
0 commit comments