Joe Bloggos
Joe Bloggos

Reputation: 889

Custom Rails Voting System Routes Not Working

Hi I have a little app that has user, question, response and vote models:

class Vote < ApplicationRecord
  belongs_to :user
  belongs_to :response

  enum vote_type: [ :upvote, :downvote]

  validates :response, uniqueness: { scope: :user }
  validates :user, uniqueness: { scope: :response }

end


class Response < ApplicationRecord
  belongs_to :question
  belongs_to :user
  has_many :votes
end


class Question < ApplicationRecord
    belongs_to :user
    has_many :responses
end

I want to create a link to upvote and downvote the response

So in the app/controllers/questions/responses/votes_controller.rb

class Questions::Responses::VotesController < ApplicationController
  before_action :authenticate_user!
  before_action :set_response


  def upvote
    @user = current_user
    vote = Vote.new
    vote.response = @response
    vote.user = @user
    if vote.save
      vote.upvote!
      redirect_to @response.question, notice: 'Response was successfully Upvoted.' 
    else
      redirect_to @response.question, notice: 'No Vote' 
    end
  end

  def downvote
    @user = current_user
    vote = Vote.new
    vote.response = @response
    vote.user = @user
    if vote.save
      vote.downvote!
      redirect_to @response.question, notice: 'Response was successfully DownVote.'
    else
      redirect_to @response.question, notice: 'No Vote' 
    end
  end

  private

  def set_response
    @response = Response.find(params[:response_id])
  end

end

I created the routes

resources :questions do
    resources :responses, module: :questions do
      resources :votes, module: :responses, only: [:upvote, :downvote]
    end
  end

but this doesn't work

when i remove the ", only: [:upvote, :downvote]"

it creates routes

question_response_votes GET    /questions/:question_id/responses/:response_id/votes(.:format)                           questions/responses/votes#index
                                      POST   /questions/:question_id/responses/:response_id/votes(.:format)                           questions/responses/votes#create
           new_question_response_vote GET    /questions/:question_id/responses/:response_id/votes/new(.:format)                       questions/responses/votes#new
          edit_question_response_vote GET    /questions/:question_id/responses/:response_id/votes/:id/edit(.:format)                  questions/responses/votes#edit
               question_response_vote GET    /questions/:question_id/responses/:response_id/votes/:id(.:format)                       questions/responses/votes#show
                                      PATCH  /questions/:question_id/responses/:response_id/votes/:id(.:format)                       questions/responses/votes#update
                                      PUT    /questions/:question_id/responses/:response_id/votes/:id(.:format)                       questions/responses/votes#update
                                      DELETE /questions/:question_id/responses/:response_id/votes/:id(.:format)                       questions/responses/votes#destroy

I only want to upvote or downvote... can someone tell me how? or what I am doing wrong?

Update

With help from the response below I found the correct routes to be

resources :questions do
    resources :responses, module: :questions do
      get 'upvote', controller: 'responses/votes', as: :upvote
      get 'downvote', controller: 'responses/votes', as: :downvote
      resource :favourite, module: :responses, only: [:create, :destroy]
    end
  end

with the links

<%= link_to question_response_upvote_path(response.question.id ,response) %>

<%= link_to question_response_downvote_path(response.question.id ,response) %>

Upvotes: 1

Views: 73

Answers (2)

Joe Bloggos
Joe Bloggos

Reputation: 889

With help from the @crachtors response I found the correct routes to be

resources :questions do
    resources :responses, module: :questions do
      get 'upvote', controller: 'responses/votes', as: :upvote
      get 'downvote', controller: 'responses/votes', as: :downvote
      resource :favourite, module: :responses, only: [:create, :destroy]
    end
  end

with the links

<%= link_to question_response_upvote_path(response.question.id ,response) %>

<%= link_to question_response_downvote_path(response.question.id ,response) %>

Upvotes: 1

Crashtor
Crashtor

Reputation: 1279

Looks like you haven't actually created the custom routes for upvote or downvote, you have only specified which actions in the controller should be resourced.

So you need to create a POST route in your routes.rb in the same format specified under POST when you run the command rake routes.

Like this:

post '/questions/:question_id/responses/:response_id/upvote' => 'votes_controller#upvote', :as => :upvote

:as => :upvote creates the upvote_path which you then can <%= link_to %> or add in the form_for however you choose to reference upvotes in your views.

Upvotes: 2

Related Questions