web-dev-qa-db-ja.com

列の組み合わせに一意の制約を追加するための移行

必要なのは、列の組み合わせに一意の制約を適用するための移行です。つまり、peopleテーブルの場合、first_namelast_NameおよびDobは一意でなければなりません。

130
rangalo

add_index :people, [:firstname, :lastname, :dob], :unique => true

229
Robert Speicher

Howmanyofme.comによると、米国だけで「John Smithという名前の46,427人がいます」とのことです。それは約127年の日です。これは人間の平均寿命を大きく上回っているので、これはDOBの衝突が数学的に確実であることを意味します。

私が言っているのは、ユニークなフィールドの特定の組み合わせが、将来、極端なユーザー/顧客のフラストレーションにつながる可能性があるということです。

必要に応じて、国民識別番号など、実際にユニークなものを検討してください。

(私はこれでパーティーに非常に遅れていることを知っていますが、それは将来の読者を助けることができます。)

22
A Fader Darkly

インデックスなしで制約を追加することもできます。これは、使用しているデータベースによって異なります。以下は、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

追加できるさまざまな制約があります。 ドキュメントを読む

18
Josh

こんにちは。たとえば、移行の一意のインデックスを列に追加できます。

add_index(:accounts, [:branch_id, :party_id], :unique => true)

または列ごとに個別の一意のインデックス

7
Bohdan

ユーザーと投稿の間の結合テーブルの典型的な例:

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

2つの同様のレコードを作成しようとすると、データベースエラー(私の場合は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

4
Dorian