Rails例外以验证唯一性

时间:2015-11-26 03:55:15

标签: ruby-on-rails

我想这样做,以便登录我网站的用户只能在问题上喜欢一次,但我也希望那些没有登录的用户也能够喜欢。

目前我这样做是为了确保登录用户只投票一次

模型

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

控制器

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

目前,如果一个用户喜欢而不登录,则会阻止未登录用户的进一步喜欢。基本上,它会阻止多个yesvotes的user_id为null / nil

2 个答案:

答案 0 :(得分:2)

这可能有用: -

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

:allow_blank或:allow_nil,它们将分别跳过blank和nil字段的验证。

答案 1 :(得分:0)

要验证多个属性,您可以使用范围:

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

我猜您正在使用设计进行身份验证。如果是这样,您可以在控制器中添加一个before过滤器,以在投票前验证用户:

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

修改: 如果user_id为空,则可以使用Proc跳过验证。

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