1

我有一个Invitation模型代表加入订阅的邀请。在任何给定时间应该只有一个Invitation具有特定email/subscription_id组合的记录,除非具有匹配email/的其他记录subscription_id也具有stateof 'declined'

鉴于 email 和 subscription_id 组合是唯一的,我目前可以验证唯一性:

我的Invitation模型:

validates :email, :uniqueness => { :scope => :subscription_id }

Rspec(通过):

it { should validate_uniqueness_of(:email).scoped_to(:subscription_id) }

state但是,如果数据库中的匹配模型的 a等于,我想跳过唯一性检查'declined'

如果现有模型的状态为“已拒绝”,则验证应通过。

首先想到的是:

validates :email, :uniqueness => { :scope => :subscription_id },
                                   :unless => lambda { |asset| asset.state == 'declined' }

但这是错误的,因为它检查新创建的模型是否具有“拒绝”状态,我想检查以前存在的记录是否具有'declined'.

我也试过这个:

validates :email, :uniqueness => { :scope => :subscription_id, :message => 'subscriptionery do' }, 
                                   :if => lambda { |asset| asset.state == 'declined' }

但这失败了,因为我认为是同样的原因。

我将如何编写检查附加范围的验证?


我想写类似下面的东西,但这只是用来帮助解释我的想法的语法:

it { should validate_uniqueness_of(:email).scoped_to(:subscription_id) } 
                                   unless MyModel.where(:email == new_object.email,
                                                        :subscription_id == new_object.subscription_id,
                                                        :state == 'declined')

更新:

我这样做了,它奏效了:

validates :email, uniqueness: { scope: :subscription_id, message: 'The email address %{value} is already associated with this subscription.' }, if: :state_of_others_are_not_declined?, on: :create

def state_of_others_are_not_declined?
  Invitation.where(email: email).where(subscription_id: subscription_id).where.not(state: 'declined').any?
end
4

1 回答 1

1

这对你有什么作用;

validate :unique_email_with_subscription_and_state


def unique_email_with_subscription_and_state
    errors.add(:email,"YOUR MESSAGE") if Invitation.where(email: self.email, subscription_id: self.subscription_id).where.not(state: 'declined').any?
end

这将选择所有匹配、匹配和未被拒绝Invitiation的 s 。如果找到任何内容,它将添加一个to 。像这样的东西emailsubscription_idstateerror:email

"SELECT invitations.* FROM invitatations WHERE email = 'me@example.com' AND subscription_id = 2 AND state <> 'declined'"  

这是期望的结果吗?

于 2014-09-16T14:11:08.537 回答