给定其他四个列作为范围,我需要验证两个列的唯一性:
validates :preference, uniqueness: { scope: [:voter_id, :term_id, :in_transaction, :transaction_destroy], message: 'must not have the same preference as another vote' }
validates :candidate, uniqueness: { scope: [:voter_id, :term_id, :in_transaction, :transaction_destroy], message: 'can only be voted for once' }
这是为了确保在同一期限内,同一交易状态下,同一投票人的唯一偏好和候选人。
问题是,in_transaction
并且transaction_destroy
是布尔值,这意味着Rails验证不起作用。
如何编写解决方法?
我正在STV选举后端。
项目的整个过程都已经完成-前端站点,数据库,结果生成,精美的动画结果差异等。我唯一无法做的就是唯一性验证。
通过STV的工作方式,每个投票者都可以输入任意数量的候选人的偏好(int)。如果消除了他们的第一优先权,他们的投票将转移到第二优先权,依此类推。所有这些都存储在council_votes
表中,以列voter_id
,candidate_id
和preference
。
用户也需要能够交换首选项。但是,给定首选项唯一性约束,单个更新会中断验证。为了解决此问题,并防止由于网络超时而导致数据丢失,我添加了事务。
客户端应用发送一条begin transaction
消息,发送其首选项更改,最后发送一条commit
消息。在交易过程中,所有更改都会创建带有的记录in_transaction: true
;用销毁创建记录in_transcation: true, transaction_destroy: true
。提交事务将首先破坏记录,然后使用正确的首选项重新创建记录。如果发生错误,它将回滚更改并通知客户端。
考虑到这是如何工作的,基本上有三组“投票”:
in_transaction
投票in_transaction && transaction_destroy
投票为了防止重复的候选者/偏好,我必须确保它们在这三组中是唯一的。但是鉴于两个状态列均为布尔值,我该怎么做?
还是会更容易改变的模式和更换in_transaction
,并transaction_destroy
与transaction_state (null|create|destroy)
和范围,与其?这似乎是一个更明智的选择。
使用自定义验证来检查现有记录是否存在:
validate :is_new_preference
def is_new_preference
!Item.exists?(preference: preference, voter_id: voter_id, term_id: term_id, in_transaction: in_transaction, transaction_destroy: transaction_destroy)
end
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句