¿Cómo puedo hacer que una columna sea única e indexarla en una migración de Ruby on Rails?


Me gustaría hacer una columna unique en el script de migración de Ruby on Rails. ¿Cuál es la mejor manera de hacerlo? También hay una manera de indexar una columna en una tabla?

Me gustaría aplicar unique columnas en una base de datos en lugar de simplemente usar :validate_uniqueness_of.

Author: Peter Mortensen, 2009-09-20

7 answers

La respuesta corta:

add_index :table_name, :column_name, unique: true

Para indexar varias columnas juntas, pasa una matriz de nombres de columna en lugar de un solo nombre de columna,

add_index :table_name, [:column_name_a, :column_name_b], unique: true

Para un control más fino, hay un método "execute" que ejecuta SQL directamente.

¡Eso es todo!

Si está haciendo esto como un reemplazo para las validaciones de modelos antiguos regulares, simplemente verifique cómo funciona. No estoy seguro de que el informe de errores al usuario será tan agradable. Siempre puedes hacer las dos cosas.

 595
Author: ndp,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-07 14:24:28

Los rails generan migración add_index_to_table_name column_name: uniq

O

Los rails generan migración add_column_name_to_table_name column_name: string:uniq: index

Genera

class AddIndexToModerators < ActiveRecord::Migration
  def change
    add_column :moderators, :username, :string
    add_index :moderators, :username, unique: true
  end
end

Si está agregando un índice a una columna existente, elimine o comente la línea add_column, o marque

add_column :moderators, :username, :string unless column_exists? :moderators, :username
 103
Author: d.danailov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-10 16:04:06

Dado que esto no se ha mencionado todavía, pero responde a la pregunta que tenía cuando encontré esta página, también puede especificar que un índice debe ser único al agregarlo a través de t.references o t.belongs_to:

create_table :accounts do |t|
  t.references :user, index: { unique: true } # or t.belongs_to

  # other columns...
end

(como mínimo de rieles 4.2.7)

 25
Author: Steve Grossi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-10 17:30:42

Si está creando una nueva tabla, puede usar el atajo en línea:

  def change
    create_table :posts do |t|
      t.string :title, null: false, index: { unique: true }
      t.timestamps
    end
  end
 13
Author: Pioz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-07 15:12:54

Estoy usando Rails 5 y las respuestas anteriores funcionan muy bien; aquí hay otra forma que también funcionó para mí (el nombre de la tabla es :people y el nombre de la columna es :email_address)

class AddIndexToEmailAddress < ActiveRecord::Migration[5.0]
  def change
    change_table :people do |t|
      t.index :email_address, unique: true
    end
  end
end
 10
Author: Nicholas Nelson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-10 16:52:42
add_index :table_name, :column_name, unique: true

Para indexar varias columnas juntas, pasa una matriz de nombres de columna en lugar de un solo nombre de columna.

 1
Author: murali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-29 08:55:15

Es posible que desee agregar un nombre para la clave única, ya que muchas veces el nombre unique_key predeterminado de rails puede ser demasiado largo para que la base de datos pueda lanzar el error.

Para agregar un nombre a su índice solo use la opción name:. La consulta de migración podría ser algo como esto -

add_index :table_name, [:column_name_a, :column_name_b, ... :column_name_n], unique: true, name: 'my_custom_index_name'

Más información - http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

 0
Author: Swaps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-05 11:39:56