简体   繁体   中英

Rails exceptions to validates uniqueness

I want to make it so that users who log into my site can only like once on a question, But I would also want people who aren't logged in to also be able to like.

currently I have this to ensure that logged in users only vote once

model

class Yesvote < ActiveRecord::Base
   belongs_to :user
   belongs_to :question
   validates_uniqueness_of :user, scope: :question
end

controller

def yesvote
    @question = Question.find(params[:id])
    if current_user != nil
        yesvote = Yesvote.create(yes: params[:yes], user: current_user, question: @question)
    else 
        yesvote = Yesvote.create(yes: params[:yes], question: @question)
    end
    if yesvote.valid?
        redirect_to :back
    else 
        flash[:danger] = "once only!"
        redirect_to :back
    end
end

currently if one user likes without logging in, it prevents further likes from un-logged in users. basically, it prevents more than one yesvotes to have a user_id of null/nil

This may helpful :-

validates_uniqueness_of :user_id, :allow_blank => true, :scope => [:question_id]

:allow_blank or :allow_nil, which will skip the validations on blank and nil fields, respectively.

To validate multiple attributes you could use scope:

class Yesvote < ActiveRecord::Base
   belongs_to :user
   belongs_to :question
   validates_uniqueness_of :user_id, scope: :question_id
end

I guess you are using devise for authentication. If so, you can add a before filter in your controller to authenticate users before voting:

before_filter: authenticate_user!, only: :yesvote

def yesvote
  @question = Question.find(params[:id])        
  yesvote = Yesvote.create(yes: params[:yes], user: current_user, question: @question)      
  redirect_to :back
end

Edit : You can use Proc to skip validation if user_id is blank.

validates_uniqueness_of :user_id, scope: :question_id, unless: Proc.new { |v| v.user_id.blank? }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM