0

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
jon snow
  • 3,062
  • 1
  • 19
  • 31
Kris
  • 123
  • 10

2 Answers2

2

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.

molnargab
  • 162
  • 7
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • Thank you for the reply and condensing the update_vote! method. The method as it is right now is a bit verbose because the course I'm currently taking is for beginners and I believe it's attempting to demonstrate the object creation-end of ruby syntax early on until I'm comfortable with the language =] – Kris May 25 '15 at 10:43
-1

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
Kris
  • 123
  • 10
  • 3
    It looks like you posted this to agree with Arup's answer. In that case, instead of posting another answer to your question, you should upvote and accept that other answer. – Dan Getz May 26 '15 at 02:47