[ruby-on-rails] 열 조합에 고유 제한 조건을 추가하기위한 마이그레이션

필요한 것은 열 조합에 고유 제약 조건을 적용하는 마이그레이션입니다. A에 대한 즉 people테이블의 조합 first_name, last_Name그리고 Dob고유해야합니다.



답변

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(:accounts, [:branch_id, :party_id], :unique => true)

또는 각 열마다 별도의 고유 색인


답변

사용자와 게시물 간 조인 테이블의 일반적인 예에서 :

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


답변