Rails: xác nhận tính duy nhất của hai cột (cùng nhau)


130

Tôi có một Releasemô hình với mediumcountrycột (trong số những người khác). Không nên có releasessự chia sẻ giống hệt medium/ countrykết hợp.

Làm thế nào tôi có thể viết điều này như là một xác nhận đường ray?


Câu trả lời:


230

Bạn có thể sử dụng xác nhận tính duy nhất với scopetùy chọn.

Ngoài ra, bạn nên thêm một chỉ mục duy nhất vào DB để ngăn các bản ghi mới vượt qua các xác nhận khi được kiểm tra cùng lúc trước khi được viết:

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

+1 cho chỉ mục, nhưng -1 cho chỉ số uniquekhông được công nhận. Đối với phần đó tôi đã sử dụng câu trả lời dưới đây.
Aleks

7
Vâng, xin lỗi, khóa xác nhận nên uniqueness, không unique. Xem các tài liệu liên kết. Sửa câu trả lời.
tompave

1
Hừm, cảm ơn, cảm ơn :) Để nhắc lại bản thân - đưa chỉ số đưa giải pháp lên cấp độ tiếp theo, và không giống như các giải pháp "mã hóa" khác mà tôi đã chạy vào, trước khi tìm thấy câu trả lời này. +1 cho điều đó
Aleks

70

Tất cả các câu trả lời ở trên đều thiếu cách xác thực tính duy nhất của nhiều thuộc tính trong một mô hình. Mã dưới đây dự định cho biết cách sử dụng nhiều thuộc tính trong một phạm vi.

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

Nó xác nhận tính duy nhất của countrytất cả các hàng với các giá trị mediumanother_medium.

Lưu ý: Đừng quên thêm chỉ mục vào cột trên, điều này đảm bảo truy xuất nhanh và thêm xác thực mức DB cho các bản ghi duy nhất.

Cập nhật: Để thêm một chỉ mục trong khi tạo bảng

t.index [:medium, :another_medium], unique: true

41

Bạn có thể truyền :scopetham số cho trình xác nhận của mình như thế này:

validates_uniqueness_of :medium, scope: :country

Xem tài liệu cho một số ví dụ khác.


8
@DennisBest Nó "hoạt động", nhưng nó không bảo vệ chống lại các điều kiện chủng tộc. Nếu hai khách hàng thực hiện các yêu cầu đồng thời, cả hai có thể vượt qua xác thực nếu không cam kết với cơ sở dữ liệu trước khi khách hàng kia được xác thực. Bạn cũng cần một ràng buộc duy nhất về cơ sở dữ liệu như trong câu trả lời của tompave.
súpdog
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.