首页 文章

具有范围和belongs_to的Mongoid验证唯一性

提问于
浏览
4

我有以下mongoid模型,带有范围验证,以防止在一个账单上多次投票 . 每个投票属于一个用户和一个组:

class Vote
  include Mongoid::Document
  field :value, :type => Symbol # can be :aye, :nay, :abstain
  field :type, :type => Symbol  # TODO can delete?

  belongs_to :user
  belongs_to :polco_group

  embedded_in :bill
  validates_uniqueness_of :value, :scope => [:polco_group_id, :user_id, :type]

end

用户可以使用以下方法向帐单添加投票:

def vote_on(bill, value)    
    if my_groups = self.polco_groups # test to make sure the user is a member of a group
      my_groups.each do |g|
          # TODO see if already voted
          bill.votes.create(:value => value, :user_id => self.id, :polco_group_id => g.id, :type => g.type)
      end
    else
      raise "no polco_groups for this user" # #{self.full_name}"
    end
  end

和一个嵌入许多的比尔课程:投票 . 这旨在允许用户将他们的投票与不同的组(“Ruby Coders”,“Women”等)相关联并且运行良好,除了数据库当前允许用户在一个账单上多次投票 . 我怎样才能让以下工作?

u = User.last
b = Bill.last
u.vote_on(b,:nay)
u.vote_on(b,:nay) -> should return a validation error

1 回答

  • 2

    Vote 上的大多数验证器都没有被解雇 . 您可以通过添加验证功能并输出内容或在其中引发异常来确认 .

    class Vote
      validate :dummy_validator_to_confirmation
    
      def dummy_validator_to_confirmation
        raise "What the hell, it is being called, then why my validations are not working?"
      end
    end
    

    如果在创建上述验证后 User#vote_on 未引发异常,则会确认 Vote 未通过 vote_on 方法触发回调 . 您需要更改代码以在 Vote 上触发回调 . 可能将其更改为类似以下内容会有所帮助:

    def vote_on(bill, value)    
      if my_groups = self.polco_groups # test to make sure the user is a member of a group
        my_groups.each do |g|
            # TODO see if already voted
            vote = bill.votes.new(:value => value, :user_id => self.id, :polco_group_id => g.id, :type => g.type)
            vote.save
        end
      else
        raise "no polco_groups for this user" # #{self.full_name}"
      end
    end
    

    在mongoid github问题跟踪器上有一个open issue,允许级联回调嵌入文档 . 现在回调仅针对正在进行持久性操作的文档触发 .

相关问题