2010-07-30 8 views

Respuesta

185

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

+7

Creo que está agregando un índice único, * no * una restricción. ¿O el índice agrega la restricción también? –

+13

No, todo está bien. ¡Mi error! La restricción única viene con el índice único. –

+5

Estoy de acuerdo con @ paul-cantrell: ¿no hay alguna manera de agregar solo una restricción, no un índice (que tenga influencias de almacenamiento de db) –

5

Hola Puede añadir índice único en su migración a las columnas, por ejemplo

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

o índices únicos separados para cada columna

+0

Lo sentimos, trabajó, primero juzgado por la edición y la migración existente, que no funcionaba, y luego añadió una nueva y funcionó, gracias. – rangalo

12

es posible que desee agregar una restricción sin una índice. Esto dependerá de la base de datos que estés usando. Debajo hay un código de migración de muestra para Postgres. (tracking_number, carrier) es una lista de las columnas que desea usar para la restricción.

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 

Existen diferentes restricciones que puede agregar. Read the docs

+9

[Documentos para PostgreSQL 9.4] (http://www.postgresql.org/docs/9.4/static/ddl-constraints.html#DDL-CONSTRAINTS-UNIQUE-CONSTRAINTS) diga: _Añadir una restricción única creará automáticamente un btree único índice en la columna o grupo de columnas utilizadas en la restricción. Una restricción de exclusividad en solo algunas filas se puede aplicar mediante la creación de un índice parcial. Así que en mi humilde opinión no hay necesidad de pasar al SQL sin formato cuando el resultado será básicamente el mismo que usar el método 'add_index'. ;) –

+3

En realidad, hay una razón: es un detalle de implementación y desaconseja [docs] (http://www.postgresql.org/docs/9.3/static/indexes-unique.html). También tenga en cuenta que no puede hacer referencia a la restricción por su nombre, ya que no se agrega a la tabla 'pg_constraint'. – kaikuchn

16

De acuerdo con howmanyofme.com, "Hay 46.427 personas llamadas John Smith" solo en los Estados Unidos. Eso es alrededor de 127 años de días. Como esto está muy por encima de la esperanza de vida promedio de un ser humano, esto significa que un choque entre DOB es matemáticamente seguro.

Todo lo que digo es que esa combinación particular de campos únicos podría llevar a una frustración extrema de usuario/cliente en el futuro.

Considere algo que es realmente único, como un número de identificación nacional, si corresponde.

(Me doy cuenta de que soy muy tarde a la fiesta con éste, pero podría ayudar a los lectores futuros.)

+1

hrm ... ciertamente tienes razón. pero probablemente fue solo un ejemplo de lo que Ian quería hacer solo para aclarar la pregunta. – eritiro

+0

Quizás. La respuesta no fue pensada para Ian, sin embargo. O de hecho Rangalo. –

1

En el ejemplo típico de una tabla de unión entre los usuarios y mensajes:

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 

Tratar de crear dos registros similares lanzará un error de base de datos (PostgreSQL en mi caso):

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" 

por ejemplo, haciendo que:

Ownership.create!(user_id: user_id, post_id: post_id) 
Ownership.create!(user_id: user_id, post_id: post_id) 

ejemplo totalmente ejecutable: https://gist.github.com/Dorian/9d641ca78dad8eb64736173614d97ced

db/schema.rb generada: https://gist.github.com/Dorian/a8449287fa62b88463f48da986c1744a

Cuestiones relacionadas