goals {
message "Now we're going to add a button people can click to cast a vote."
}
steps {
step "Add a new controller action for voting" do
message "Edit `app/controllers/topics_controller.rb` to add the new method. You can put it anywhere in the file as long as it appears before the word `private`."
source_code :ruby, <<-RUBY
def upvote
@topic = Topic.find(params[:id])
@topic.votes.create
redirect_to(topics_path)
end
RUBY
message <<-MARKDOWN
* `@topic = Topic.find(params[:id])` finds the topic in the database with that id and stores it in the variable `@topic`.
* `@topic.votes.create` creates a new vote for the current topic and saves it in the database.
* `redirect_to(topics_path)` tells the browser to go back to topics_path (the topics list).
MARKDOWN
end
step "Add a new route for voting" do
message "Open `config/routes.rb` and find the section that looks like this:"
source_code :ruby, <<-RUBY
resources :topics
RUBY
message "Replace that line so it looks like this:"
source_code :ruby, <<-RUBY
resources :topics do
member do
post 'upvote'
end
end
RUBY
message <<-MARKDOWN
Verify that route route was added successfully by checking the output of `rake routes` or [http://localhost:3000/rails/info](http://localhost:3000/rails/info). You should see a line that looks like this:
```
Prefix Verb URI Pattern Controller#Action
upvote_topic POST /topics/:id/upvote(.:format) topics#upvote
```
MARKDOWN
end
step "Add the button to the view" do
message "Edit `app/views/topics/index.html.erb` so that the bottom loop looks like this:"
source_code :erb, <<-HTML
<% @topics.each do |topic| %>
<tr>
<td><%= topic.title %></td>
<td><%= topic.description %></td>
<td><%= pluralize(topic.votes.count, "vote") %></td>
<td><%= button_to '+1', upvote_topic_path(topic), method: :post %></td>
<td><%= link_to 'Show', topic %></td>
<td><%= link_to 'Edit', edit_topic_path(topic) %></td>
<td><%= link_to 'Destroy', topic, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
HTML
message <<-MARKDOWN
* `pluralize(topic.votes.count, "vote")` displays the number of votes the topic has, plus the word 'vote' or 'votes' accordingly.
* `button_to '+1'` creates an html button with the text '+1'.
* `topic_upvote_path(topic)` creates the appropriate URL for the action we want to invoke. In this case, we want to upvote the current topic.
* `topic_upvote_path(topic)` would return `/topics/42/upvote` (if topic.id was 42)
* `method: :post` ensures we do the create action of CRUD, not the read action.
MARKDOWN
end
step "Confirm your changes in the browser" do
message "Go back to <http://localhost:3000/topics> and play."
message "Revel in the fact that you didn't have to restart the server to see these changes. Awesome, no?"
end
}
tip {
message "<h2>Pair teach again with sticky notes and paper</h2>"
message "It's talking time again! Describe what you've just done, and the steps you took, with a partner."
message "If there are things you're unsure about, write them down too, then ask a teacher to explain."
}
insert 'consider_deploying'
next_step "redirect_to_the_topics_list_after_creating_a_new_topic"