У меня есть модель купона, которая может иметь несколько валют с одинаковым кодом купона.Как сделать toa-matchers использовать определенный набор значений для поля?
Так я проверить это так:
validates :code, presence: true, uniqueness: { case_sensitive: false, scope: :currency }, length: { in: 1..40 }
и проверить его так:
it { should validate_uniqueness_of(:code).case_insensitive.scoped_to(:currency) }
Но также купон переписывает атрибут валюты принимать как символ валюты ($), и это код ISO (ДОЛЛАР США). Он переписывает символ в соответствующий код ISO:
# Convert currency symbols to ISO code
def currency=(value)
return write_attribute(:currency, nil) if value.blank?
write_attribute(:currency, currency_to_iso(value.strip))
end
def currency_to_iso(symbol_or_iso)
return unless symbol_or_iso
(Money::Currency.find(symbol_or_iso) || Money::Currency.find_by_symbol(symbol_or_iso)).try(:iso_code)
end
Когда валюта код неверен, он преобразуется в nil
.
Так Shoulda-matchers выдает ошибку:
Coupon did not properly validate that :code is case-insensitively unique
within the scope of :currency.
After taking the given Coupon, whose :code is ‹"t8u"›, and saving it
as the existing record, then making a new Coupon and setting its :code
to ‹"t8u"› as well and its :currency to a different value, ‹"dummy
value"› (read back as ‹nil›), the matcher expected the new Coupon to
be valid, but it was invalid instead, producing these validation
errors:
* code: ["has already been taken"]
Как сделать Shoulda-спичка использовать только действительные коды валют, как FFaker::Currency
или предопределенный список?