不久之前,我找到了一个关于如何在我的连接表中创建唯一性验证的solution:
class Album < ApplicationRecord
has_many :album_artists
has_many :artists, through: :album_artists
end
class AlbumArtist < ApplicationRecord
belongs_to :album
belongs_to :artist
validate :uniqueness_of_album_artist
private
def uniqueness_of_album_artist
if self.artist.albums.where(name: self.album.name).any?
album.errors[:base] << "Artist already has an album by this name"
end
end
end
class Artist < ApplicationRecord
has_many :album_artists
has_many :albums, through: :album_artists
end
我现在想为我的AlbumArtist's
uniqueness_of_album_artist
验证程序编写测试。这就是我想出的:
it 'validates that album is unique to artist' do
artist = FactoryGirl.create(:artist)
artist.albums.push(FactoryGirl.create(:album, name: "Test"), FactoryGirl.create(:album, name: "Test"))
album_artist = artist.album_artists.last
expect(album_artist).to be_invalid
expect(album_artist.errors[:base]).to include('Artist already has an album by this name')
end
奇怪的是,我的测试失败了:
Failure/Error: expect(album_artist).to be_invalid
expected `#<AlbumArtist id: 2, artist_id: 1, album_id: 2, created_at: "2016-07-05 14:57:13", updated_at: "2016-07-05 14:57:13">.invalid?` to return true, got false
我继续前进并在此之后做了一些调试但是当我测试艺术家是否有两个同名的专辑时,它会返回true
,从而证明它无效。
p artist.album_artists.first.album.name == artist.album_artists.last.album.name # returns true
这里发生了什么?
答案 0 :(得分:0)
您的测试失败,因为artist_album有效。发生的事情是,由于您的验证,最后一个永远不会创建,但是当它失败时它不会被提升。试试这个:
it 'validates that album is unique to artist' do
artist = FactoryGirl.create(:artist)
album = FactoryGirl.create(:album)
valid_artist_album = AlbumArtist.create(artist: artist, album: album)
invalid_album_artist = AlbumArtist.new(artist: artist, album: album)
expect(invalid_album_artist).to be_invalid
end
我正在编辑此帖子以使用代码突出显示。所以,如果你这样做:会发生什么?
it 'validates that album is unique to artist' do
artist = FactoryGirl.create(:artist)
album = FactoryGirl.create(:album)
AlbumArtist.create!(artist: artist, album: album)
invalid_album_artist = AlbumArtist.create!(artist: artist, album: album)
expect(invalid_album_artist).to be_invalid
end
会发生什么?如果您将其设置为期望行,则验证无效。如果您在第二次创建时引发异常,那么您的验证工作正常。我认为,既然你说早期的测试表明invalid_album_artist实际上是有效的,你的验证不起作用,但改变你的测试将确认这一点。