답변:
add_index :people, [:firstname, :lastname, :dob], :unique => true
howmanyofme.com에 따르면 미국에만 "John Smith라는 46,427 명의 사람들이있다"고합니다. 약 127 년입니다. 이것은 인간의 평균 수명보다 훨씬 길기 때문에 이것은 DOB 충돌이 수학적으로 확실하다는 것을 의미합니다.
내가 말하고 싶은 것은 고유 필드의 특정 조합이 미래에 극단적 인 사용자 / 고객 불만을 야기 할 수 있다는 것입니다.
적절한 경우 국가 식별 번호와 같이 실제로 고유 한 것을 고려하십시오.
(나는이 파티에 매우 늦었다는 것을 알고 있지만 앞으로 독자에게 도움이 될 수 있습니다.)
인덱스없이 제약 조건을 추가 할 수 있습니다. 사용중인 데이터베이스에 따라 다릅니다. 다음은 Postgres의 샘플 마이그레이션 코드입니다. (tracking_number, carrier)
제약 조건에 사용하려는 열 목록입니다.
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
추가 할 수있는 다른 구속 조건이 있습니다. 문서를 읽으십시오
add_index
메소드 를 사용하는 것과 동일 할 때 원시 SQL로 드롭 할 필요가 없습니다 . ;)
사용자와 게시물 간 조인 테이블의 일반적인 예에서 :
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
두 개의 유사한 레코드를 만들려고하면 데이터베이스 오류가 발생합니다 (필자의 경우 Postgres).
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"
예를 들면 :
Ownership.create!(user_id: user_id, post_id: post_id)
Ownership.create!(user_id: user_id, post_id: post_id)
완전히 실행 가능한 예 : https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced
db/schema.rb
생성 : https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a
완전성을 위해 혼동을 피하기 위해 여기에 동일한 작업을 수행하는 3 가지 방법
이 있습니다. Rails 5.2+의 열 조합에 명명 된 고유 제한 조건 추가
광고주에 속하는 Locations 테이블이 있고 reference_code 열이 있고 광고 주당 하나의 참조 코드 만 원한다고 가정 해 봅시다. 따라서 열 조합에 고유 제한 조건을 추가하고 이름을 지정하려고합니다.
하다:
rails g migration AddUniquenessConstraintToLocations
그리고 마이그레이션을 다음과 같은 라이너로 만드십시오.
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
또는이 블록 버전.
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
또는이 원시 SQL 버전
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
이 중 하나라도 같은 결과를 낼 것입니다. schema.rb