Câu trả lời:
add_index :people, [:firstname, :lastname, :dob], :unique => true
Theo howmanyofme.com, "Có 46.427 người tên John Smith" chỉ riêng ở Hoa Kỳ. Đó là khoảng 127 năm. Vì điều này vượt quá tuổi thọ trung bình của một con người, điều này có nghĩa là một cuộc đụng độ DOB là chắc chắn về mặt toán học.
Tất cả những gì tôi nói là sự kết hợp đặc biệt của các lĩnh vực duy nhất có thể dẫn đến sự thất vọng của người dùng / khách hàng trong tương lai.
Hãy xem xét một cái gì đó thực sự độc đáo, như số nhận dạng quốc gia, nếu phù hợp.
(Tôi nhận ra rằng tôi đến bữa tiệc rất muộn với điều này, nhưng nó có thể giúp những độc giả tương lai.)
Bạn có thể muốn thêm một ràng buộc mà không có chỉ mục. Điều này sẽ phụ thuộc vào cơ sở dữ liệu bạn đang sử dụng. Dưới đây là mã di chuyển mẫu cho Postgres. (tracking_number, carrier)
là danh sách các cột bạn muốn sử dụng cho ràng buộc.
class AddUniqeConstraintToShipments < ActiveRecord::Migration
def up
execute <<-SQL
alter table shipments
add constraint shipment_tracking_number unique (tracking_number, carrier);
SQL
end
def down
execute <<-SQL
alter table shipments
drop constraint if exists shipment_tracking_number;
SQL
end
end
Có những ràng buộc khác nhau mà bạn có thể thêm. Đọc tài liệu
add_index
phương thức. ;)
Xin chào Bạn có thể thêm chỉ mục duy nhất trong di chuyển của bạn vào các cột chẳng hạn
add_index(:accounts, [:branch_id, :party_id], :unique => true)
hoặc tách các chỉ mục duy nhất cho mỗi cột
Trong ví dụ điển hình về bảng tham gia giữa người dùng và bài đăng:
create_table :users
create_table :posts
create_table :ownerships do |t|
t.belongs_to :user, foreign_key: true, null: false
t.belongs_to :post, foreign_key: true, null: false
end
add_index :ownerships, [:user_id, :post_id], unique: true
Cố gắng tạo hai bản ghi tương tự sẽ gây ra lỗi cơ sở dữ liệu (Postgres trong trường hợp của tôi):
ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_ownerships_on_user_id_and_post_id"
DETAIL: Key (user_id, post_id)=(1, 1) already exists.
: INSERT INTO "ownerships" ("user_id", "post_id") VALUES ($1, $2) RETURNING "id"
ví dụ: làm điều đó:
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
Ví dụ đầy đủ có thể chạy: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
đã tạo: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
Để hoàn thiện hơn và để tránh nhầm lẫn, đây là 3 cách thực hiện tương tự:
Thêm một ràng buộc duy nhất có tên vào tổ hợp các cột trong Rails 5.2+
Giả sử chúng ta có bảng Vị trí thuộc về một nhà quảng cáo và có cột tham chiếu_code và bạn chỉ muốn 1 mã tham chiếu cho mỗi nhà quảng cáo. vì vậy bạn muốn thêm một ràng buộc duy nhất cho sự kết hợp của các cột và đặt tên cho nó.
Làm:
rails g migration AddUniquenessConstraintToLocations
Và làm cho di chuyển của bạn trông giống như một lớp lót này:
class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
def change
add_index :locations, [:reference_code, :advertiser_id], unique: true, name: 'uniq_reference_code_per_advertiser'
end
end
HOẶC phiên bản khối này.
class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
def change
change_table :locations do |t|
t.index ['reference_code', 'advertiser_id'], name: 'uniq_reference_code_per_advertiser', unique: true
end
end
end
HOẶC phiên bản SQL thô này
class AddUniquenessConstraintToLocations < ActiveRecord::Migration[5.2]
def change
execute <<-SQL
ALTER TABLE locations
ADD CONSTRAINT uniq_reference_code_per_advertiser UNIQUE (reference_code, advertiser_id);
SQL
end
end
Bất kỳ trong số này sẽ có kết quả tương tự, kiểm tra của bạn schema.rb