我有3个型号,用户,游戏和播放器。用户和游戏之间基本上存在多对多关系,玩家作为联接表,除了玩家有其他信息,因此它有自己的模型。
玩家需要游戏ID和用户ID的唯一组合,所以我试着在玩家中说:
validates_uniqueness_of :user_id, :scope => :game_id
然后在我的规范中,我说(使用shoulda匹配器):
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...
知道出了什么问题吗?
答案 0 :(得分:9)
这是known issue。如果作用域字段依赖于模型并且也设置为:null => false
,则会出现此错误。
答案 1 :(得分:6)
虽然这是一个已知问题,但还是有办法解决它。
如果您首先创建一个记录然后测试唯一性验证,它将起作用。
所以,而不是简单地写
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
答案 2 :(得分:1)
您可以阅读官方源代码警告here
中提到的问题和解决方案一个解决方案是:
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
答案 3 :(得分:1)
对于今天遇到此问题的人来说,这是一个更新的解决方案。
添加主题,以便测试具有值记录。
另外,请注意较新的RSpec语法。
subject { create(:player) }
it { is_expected.to validate_uniqueness_of(:user_id).scoped_to(:game_id)}
查看the file on github了解详情