Skip to content

Instantly share code, notes, and snippets.

@mattraykowski
Created April 21, 2014 18:02
Show Gist options
  • Save mattraykowski/11150871 to your computer and use it in GitHub Desktop.
Save mattraykowski/11150871 to your computer and use it in GitHub Desktop.
Scoped Uniquess Validation throwing an error erroneously.
Problem:
So here, if I go into the console and run SuggestionVote.count I get 3 votes total by 2 other user ID's which are 2 and 3.
I log in as user ID 1, which has no suggestion votes. I click on the vote link and I get an error flashed:
Problem: ["User You can only vote once for a suggestion."]
I go back into the Rails console and do SuggestionVote.count and it now it shows 4.
So I'm getting the error message but it is creating the entry, but only the first time. If I manually go to the vote link again and recheck the Rails console I'm still at 4 votes - it is indeed not allowing multiple votes. Why it gives me the error but still creates the vote is a mystery.
Additionally the specs all pass successfully. So underlying the code works as it should. Could this be related to Turbolinks in some way?
class SuggestionVote < ActiveRecord::Base
belongs_to :user
belongs_to :suggestion
validates :user_id, uniqueness: { scope: :suggestion_id, message: "You can only vote once for a suggestion." }
end
class SuggestionVotesController < ApplicationController
before_action :authenticate_user!
before_action :set_suggestion
def vote
@suggestion_vote = SuggestionVote.new(suggestion: @suggestion, user: current_user)
respond_to do |format|
if @suggestion_vote.save
format.html { redirect_to suggestions_path, notice: "Voted for #{@suggestion.title}" }
format.json { render action: 'show', status: :created, location: suggestions_path }
else
format.html { redirect_to suggestions_path, alert: "Problem: #{@suggestion_vote.errors.full_messages}" }
format.json { render json: @suggestion_vote.errors.full_messages, status: :unprocessable_entity }
end
end
end
def unvote
@suggestion_votes = SuggestionVote.where('suggestion_id = ? and user_id = ?', @suggestion.id, current_user.id)
@suggestion_votes.first.destroy
respond_to do |format|
format.html { redirect_to suggestions_path }
format.json { head :no_content }
end
end
private
def set_suggestion
@suggestion = Suggestion.find(params[:id])
end
end
require 'spec_helper'
describe SuggestionVotesController do
login_user
before(:each) { @suggestion = FactoryGirl.create(:suggestion, creator: @user) }
describe "GET 'vote'" do
#before(:each) { @suggestion = FactoryGirl.create(:suggestion, creator: @user) }
describe "when not voted for already" do
it "redirects to all suggestions" do
get :vote, {id: @suggestion.to_param}
response.should redirect_to suggestions_path
end
it "adds a new vote" do
expect {
get :vote, {id: @suggestion.to_param}
}.to change(SuggestionVote, :count).by(1)
end
it "adds a flash notice notifying the user about their vote" do
get :vote, {id: @suggestion.to_param}
flash[:notice].should =~ /Voted for/i
end
end
describe "when already voted for" do
before(:each) { FactoryGirl.create(:suggestion_vote, suggestion: @suggestion, user: @user) }
it "redirects to all suggestions" do
get :vote, {id: @suggestion.to_param}
response.should redirect_to suggestions_path
end
it "adds a flash notice notifying the user about their vote" do
get :vote, {id: @suggestion.to_param}
flash[:alert].should =~ /Problem: /i
end
end
end
describe "GET 'unvote'" do
before(:each) { FactoryGirl.create(:suggestion_vote, suggestion: @suggestion, user: @user) }
it "redirects to all suggestions" do
delete :unvote, {id: @suggestion.id}
response.should redirect_to suggestions_path
end
it "adds a new vote" do
expect {
delete :unvote, {id: @suggestion.id}
}.to change(SuggestionVote, :count).by(-1)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment