1

Invitationサブスクリプションへの招待を表すモデルがあります。一致する/を持つ他のレコードにもofがない限り、特定の/の組み合わせInvitationを持つ特定の時点で1 つだけ存在する必要があります。emailsubscription_idemailsubscription_idstate'declined'

email と subscription_id の組み合わせが一意であることを考えると、現在、一意性を検証できます。

私のInvitationモデル:

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

Rspec (パス):

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

stateただし、データベース内の一致するモデルが に等しい場合、一意性チェックをスキップしたいと思います'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