shoulda匹配器应该validate_uniqueness_of与范围失败

bdw*_*ain 11 rspec ruby-on-rails shoulda

我有3个型号,用户,游戏和播放器.用户和游戏之间基本上存在多对多的关系,玩家作为联接表,除了玩家有其他信息,因此它有自己的模型.

玩家需要游戏ID和用户ID的唯一组合,所以我试着在玩家中说:

validates_uniqueness_of :user_id, :scope => :game_id
Run Code Online (Sandbox Code Playgroud)

然后在我的规范中,我说(使用shoulda matchers):

it { should validate_uniqueness_of(:user_id).scoped_to(:game_id)}
Run Code Online (Sandbox Code Playgroud)

以下是玩家定义的关系:

belongs_to :game, :inverse_of => :players
belongs_to :user, :inverse_of => :players
Run Code Online (Sandbox Code Playgroud)

但我在该规范上得到一个ActiveRecord :: statementinvalid错误

ActiveRecord::StatementInvalid: Mysql2::Error: Column 'game_id' cannot be null: INSERT INTO `players` ETC...
Run Code Online (Sandbox Code Playgroud)

知道出了什么问题吗?

kid*_*ils 9

这是一个众所周知的问题.如果作用域字段依赖于模型并且也设置为,则会出现此错误:null => false.

另外,看看rails列不能为null:


Jes*_*ung 6

虽然这是一个已知问题,但还是有办法解决它.

如果您首先创建一个记录,然后测试唯一性验证,它将起作用.

所以,而不是简单的写作

it { should validate_uniqueness_of(:user_id) }
Run Code Online (Sandbox Code Playgroud)

你可以写

it do
  FactoryGirl.create(:player)
  should validate_uniqueness_of(:user_id)
end
Run Code Online (Sandbox Code Playgroud)

并且唯一性验证规范将起作用.

参考:http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/frames

  • 或者`it {expect(create(:label)).到validate_uniqueness_of(:value).scoped_to(:question_id)}`用rspec3语法将所有内容放在一条平滑线上. (3认同)