shoulda matchers должны проверять уникальность сбоя с помощью scope

у меня есть 3 модели, пользователь, игра и игрок. Существует в основном много отношений между пользователями и играми, с игроками в качестве таблицы join, за исключением того, что у игроков есть другая информация, поэтому у нее есть своя собственная модель.

игроку нужна уникальная комбинация идентификатора игры и идентификатора пользователя, поэтому я попытался сказать в игроке:

validates_uniqueness_of :user_id, :scope => :game_id

и затем в моей спецификации я сказал (используя shoulda matchers):

it { should validate_uniqueness_of(:user_id).scoped_to(:game_id)}

вот отношения, которые игрок определяет:

belongs_to :game, :inverse_of => :players
belongs_to :user, :inverse_of => :players

еще Я получаю ошибку ActiveRecord:: statementinvalid на этой спецификации

ActiveRecord::StatementInvalid: Mysql2::Error: Column 'game_id' cannot be null: INSERT INTO `players` ETC...

есть идеи, что происходит не так?

4 ответов


Это известная проблема. Это дает эту ошибку, если поле области зависит от модели и также имеет значение :null => false.

кроме того, посмотрите на столбец rails не может быть null:


хотя это известная проблема, есть способ обойти ее.

Если вы сначала создадите запись, а затем проверите проверку уникальности, она будет работать.

Итак, вместо того, чтобы просто писать

it { should validate_uniqueness_of(:user_id) }

можно писать

it do
  FactoryGirl.create(:player)
  should validate_uniqueness_of(:user_id)
end

и спецификация проверки уникальности будет работать.

ссылка:http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/frames


вы можете прочитать о проблеме и решениях, упомянутых в официальном исходном коде caveat здесь

одно решение:

describe Player do
  describe "validations" do
    it do
      expect(Player.new(game_id: 1)).
        to validate_uniqueness_of(:user_id).
        scoped_to(:game_id)
    end
  end
end

для людей, имеющих эту проблему сегодня здесь новые решения.

добавьте тему, чтобы тесты имели запись со значениями.

также обратите внимание на более новый синтаксис RSpec.

    subject { create(:player) }

    it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:game_id)}

проверить файл на github дополнительная информация