Reputation: 3814
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
Upvotes: 0
Views: 3170
Reputation: 196
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
@suggestion.update_attribute(:votes, '1')
If you check the documentation for that method, it sets the value of the attribute votes
to 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:
@suggestion.update_attribute(:votes, @suggestion.votes + 1)
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_save
callback with increment
without the bang.
Upvotes: 5
Reputation: 346
This seems more suitable in the model. I suggest creating a like
method inside the model like so:
def like
self.increment!(:votes)
end
Now you can do something like this:
@suggestion = Suggestion.find(params[:id])
@suggestion.like
Note: increment!, with the exclamation point also performs the save action
Upvotes: 6