I have the following code in my Rails 3 application:
def like
@suggestion = Suggestion.find(params[:id])
Suggestion.update_all("votes = (votes + 1)")
redirect_to suggestions_url
end
def dislike
@suggestion = Suggestion.find(params[:id])
Suggestion.update_all("votes = (votes - 1)")
redirect_to suggestions_url
end
It’s working, but rather than updating the current suggestion it’s updating them all. So I changed it to:
def like
@suggestion = Suggestion.find(params[:id])
@suggestion.update_all("votes = (votes + 1)")
redirect_to suggestions_url
end
def dislike
@suggestion = Suggestion.find(params[:id])
@suggestion.update_all("votes = (votes - 1)")
redirect_to suggestions_url
end
but then I get:
undefined method `update_all' for #<Suggestion:0x007f87c2b918a0>
So then I tried @suggestion.update_attribute(:votes, '1') but that resets the value to 1 instead of incrementing it.
What’s the correct way to achieve this? I just want the integer (votes) of the current suggestion to increment/decrease by 1 on each save.
I’ve also tried the following with no luck:
def like
@suggestion = Suggestion.find(params[:id])
@suggestion.increment(:votes)
redirect_to suggestions_url
end
A couple things. It sounds like what you want is a controller action that increments an attribute by one. You were probably closest with the code
If you check the documentation for that method, it sets the value of the attribute
votesto the second arguement, the string'1', on the object,@suggestion, and its corresponding row in the database. Instead of setting it to'1', you want to set it to the incremented value:Ethan suggested using the convenience method, increment!, which works just the same.
Now, if you wanted to actually auto-increment each time the object gets saved (as in something else about the object gets altered, you’d want to use the
:before_savecallback withincrementwithout the bang.