Как проверить уникальность атрибута в ассоциации - PullRequest
0 голосов
/ 22 мая 2018

Учитывая, что пользователь может иметь _many адреса, я пытаюсь проверить, что у данного пользователя может быть только один адрес для данного address_type.Например, у пользователя может быть основной адрес и адрес выставления счета, но у пользователя не может быть двух основных адресов.Как применить это правило в моей модели и как его протестировать?Мое настоящее предположение состоит в том, что мне нужно проверить уникальность address_type в пределах user_id, но этот код предотвращает существование двух адресов одного типа.Я видел, как другие люди писали код, очень похожий на этот, но проверяя строки, а не перечисления.

<!-- language: lang-ruby -->
# user.rb
class User < ApplicationRecord
  has_many :addresses
end

# address.rb
class Address < ApplicationRecord
  belongs_to :user
  enum :address_type => { :primary, :mailing, :billing }
  validates :address_type, :uniqueness => { :scope => :user_id }
end

1 Ответ

0 голосов
/ 22 мая 2018

Проверка уникальности Rails прекрасно работает с целочисленными столбцами.Однако ваше перечисление недопустимо в синтаксисе Ruby.

class Address < ApplicationRecord
  belongs_to :user
  enum :address_type => [ :primary, :mailing, :billing ]
  # or preferably with Ruby 2.0+ hash syntax
   enum address_type: [ :primary, :mailing, :billing ]
  # ...
end

Вы можете проверить валидацию, вызвав .valid? в экземпляре модели и проверив объект error :

require 'rails_helper'

RSpec.describe Address, type: :model do
  let(:user) { create(:user) }
  it "should require the user id to be unique" do
    Address.create(user: user, address_type: :primary)
    duplicate = Address.new(user: user, address_type: :primary)
    expect(duplicate.valid?).to be_falsy
    expect(duplicate.errors.full_messages_for(:address_type)).to include "Address type has already been taken"
  end
end

Остерегайтесь только проверки expect(duplicate.valid?).to be_falsy и expect(duplicate.valid?), так как это может привести к ложным срабатываниям / отрицаниям.Вместо этого проверьте конкретное сообщение об ошибке или ключ. Должны-соответствовать довольно хорош для этой цели, но не является строго необходимым.

require 'rails_helper'

RSpec.describe Address, type: :model do
  # shoulda-matchers takes care of the boilerplate
  it { should validate_uniqueness_of(:address_type).scoped_to(:user_id) }
end

Вам также следует рассмотреть возможность добавления составного уникального индекса на addresses.address_type и addresses.user_id, поскольку это предотвратит проблемы с расой .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...