Reputation: 133
I have a prompt asking to write my up_vote and down_vote methods in only two lines using 'redirect_to' and the 'update_vote!' method as presented below. Implementing redirect_to is easy enough, but I'm not quite sure how to write my up/down_vote methods concisely using the existing 'update_vote!' method. Any help is appreciated.
class VotesController < ApplicationController
before_action :load_post_and_vote
def up_vote
if @vote
@vote.update_attribute(:value, 1)
else
@vote = current_user.votes.create(value: 1, post: @post)
end
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
def down_vote
if @vote
@vote.update_attribute(:value, -1)
else
@vote = current_user.votes.create(value: -1, post: @post)
end
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
private
def load_post_and_vote
@post = Post.find(params[:post_id])
@vote = @post.votes.where(user_id: current_user.id).first
end
def update_vote!(new_value)
if @vote
authorize @vote, :update?
@vote.update_attribute(:value, new_value)
else
@vote = current_user.votes.build(value: new_value, post: @post)
authorize @vote, :create
@vote.save
end
end
end
Upvotes: 0
Views: 87
Reputation: 133
seems that answer was easy enough =]
def up_vote
update_vote(1)
redirect_to :back
end
def down_vote
update_vote(-1)
redirect_to :back
end
Upvotes: -1
Reputation: 118289
You should invoke the update_vote!
method. How about:
def up_vote
update_vote!(1)
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
def down_vote
update_vote!(-1)
# http://apidoc.com/rails/ActionController/Base/redirect_to
redirect_to :back
end
Also your method can be re-written as :
def update_vote!(new_value)
Vote.find_or_create_by post: @post do |v|
authorize v, :update?
v.user_id = current_user.id
v.value = new_value
v.save!
end
end
Read find_or_create_by.
Upvotes: 2