Rails: memvalidasi keunikan dua kolom (bersama-sama)

Jawaban:

230

Anda dapat menggunakan validasi keunikan dengan scopeopsi.

Selain itu, Anda harus menambahkan indeks unik ke DB untuk mencegah record baru lolos validasi saat diperiksa pada saat yang sama sebelum ditulis:

class AddUniqueIndexToReleases < ActiveRecord::Migration
  def change
    add_index :releases, [:country, :medium], unique: true
  end
end



class Release < ActiveRecord::Base
  validates :country, uniqueness: { scope: :medium }
end
tompave
sumber
+1 untuk indeks, tetapi -1 untuk yang uniquetidak dikenali. Untuk bagian itu saya telah menggunakan jawaban di bawah ini.
Aleks
7
Ya, maaf, kunci validasinya seharusnya uniqueness, bukan unique. Lihat dokumentasi terkait. Memperbaiki jawabannya.
tompave
1
Hm, bagus, terima kasih :) Ulangi lagi - menempatkan indeks akan membawa solusi ke level berikutnya, dan tidak seperti solusi "pengkodean" lainnya yang pernah saya hadapi, sebelum menemukan jawaban ini. 1 untuk itu
Aleks
70

Semua jawaban di atas tidak memiliki cara memvalidasi keunikan beberapa atribut dalam sebuah model. Kode di bawah ini bermaksud untuk memberi tahu cara menggunakan beberapa atribut dalam satu ruang lingkup.

validates :country, uniqueness: { scope: [:medium, :another_medium] }

Ini memvalidasi keunikan countrydi semua baris dengan nilai mediumdan another_medium.

Catatan: Jangan lupa untuk menambahkan indeks pada kolom di atas, ini menjamin pengambilan cepat dan menambahkan validasi tingkat DB untuk catatan unik.

Pembaruan: Untuk menambahkan indeks saat membuat tabel

t.index [:medium, :another_medium], unique: true
Aamir
sumber
41

Anda dapat mengirimkan :scopeparameter ke validator Anda seperti ini:

validates_uniqueness_of :medium, scope: :country

Lihat dokumentasi untuk beberapa contoh lainnya.

KM Rakibul Islam
sumber
8
@DennisBest Ini "berhasil", tetapi tidak melindungi dari kondisi balapan. Jika dua klien membuat permintaan secara bersamaan, mereka berdua bisa lolos validasi jika tidak ada yang berkomitmen ke database sebelum yang lain divalidasi. Anda juga membutuhkan batasan unik database seperti pada jawaban tompave.
anjing sup