Thanks for looking. I am learning rails and am building a web app. I am trying to be “RESTful” and thinking in those terms. Therefore, I am looking at my data as a resource. Suppose I have a table called microposts and a column “votes” in which it counts how many people upvoted or downvoted. I have it working this way:
In the view:
<td>
<%= form_for feed_item do |f| %>
<div><%= hidden_field_tag 'todo', 'upvote' %></div>
<div class="action"><%= f.submit "Up" %></div>
<% end %>
</td>
<td>
<%= form_for feed_item do |f| %>
<div><%= hidden_field_tag 'todo', 'downvote' %></div>
<div class="action"><%= f.submit "Down" %></div>
<% end %>
<td>
When, a user clicks on the button, it calls the “update” method in the controller. Then, in the controller, I have this in update:
def update
@todo = params[:todo]
if @todo == "upvote"
Micropost.find(params[:id]).increment!(:votes)
flash[:success] = "Increase micropost vote"
redirect_to root_path
elsif @todo == "downvote"
Micropost.find(params[:id]).decrement!(:votes)
flash[:success] = "Decrease micropost vote"
redirect_to root_path
else
redirect_to root_path
end
end
I pass a hidden field to know if the button pressed is an “upvote” or a “downvote”. So, if I want to change any other micropost attribute, I need to have more and more if statements. I don’t think I am doing this right. What is the rails way to update attributes or a record in the DB?
Thanks much!
A more RESTful reworking is to define each of your actions as a separate route, GET if you must, POST ideally, to receive each of these types of calls:
Don’t forget to create methods like
load_micropostto handle routine loading of models. There’s no point in having several different calls strewn about your method that, at some point in the future, might require adjusting.You’d route these like this:
Another thing you might want to consider is adding a table that records who voted for what so you can audit and adjust if required. This makes it easy to unwind any fraudulent activity without having to reset the votes wholesale.
You can also make simple links that POST if you ask for them:
This will take care of rendering whatever form elements are required.