Reputation: 889
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
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
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