验证HABTM关联中{name}的唯一性

时间:2016-01-07 23:43:31

标签: ruby-on-rails validation activerecord model unique

我有一个Artist模型,在HABTM关联中有很多Album个。虽然我想允许两张不同的专辑有相同的名字,但我想确保一个艺术家的收藏品中没有两个。到目前为止的例子:

artist_1 = Artist.create(name: "Jay-Z")
artist_2 = Artist.create(name: "The Beatles")

album_1 = Album.create(name: "The Black Album", artist_ids: [1])

album_2 = Album.create(name: "The Black Album", artist_ids: [1])
=> Should return error

album_2 = Album.create(name: "The Black Album", artist_ids: [2])
=> Should not return an error

我首先考虑验证Album模型中名称的唯一性,但在尝试创建新对象时出现此错误:

SQLite3::SQLException: no such column: albums.artist_id: SELECT 1 AS one FROM "albums" WHERE ("albums"."name" = 'The Black Album' AND "albums"."artist_id" IS NULL) LIMIT 1

然后我考虑将验证放在我的连接模型AlbumArtist中,但得到错误undefined method 'name'name是相册属性之一):

undefined method `name' for #<AlbumArtist:0x007f8e1fc335e8>

我怎样才能让它发挥作用?

class Album < ActiveRecord::Base
    has_many :album_artists
    has_many :artist, through: :album_artists
end

class AlbumArtist < ActiveRecord::Base
  belongs_to :album
  belongs_to :artist

  # validates_uniqueness_of :name, scope: [:artist_id]
end

class Artist < ActiveRecord::Base
  has_many :album_artists
  has_many :albums, through: :album_artists

  # validates_uniqueness_of :name, scope: [:artist_id]
end

模式

create_table "albums", force: :cascade do |t|
  t.string   "name"
end

create_table "album_artists", force: :cascade do |t|
  t.integer  "album_id"
  t.integer  "artist_id"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "album_artists", ["album_id"], name: "index_album_artists_on_album_id"
add_index "album_artists", ["artist_id"], name: "index_album_artists_on_artist_id"

create_table "artists", force: :cascade do |t|
  t.string   "name"
end

1 个答案:

答案 0 :(得分:1)

在这种情况下最直接的方法是在关系模型中放置一个自定义验证器:

myStyleSheet.css

如果您还没有索引,可能还需要在名称列中添加索引。