如何使列唯一并在Ruby on Rails迁移中将其编入索引?

Tam*_*Tam 391 ruby-on-rails

我想unique在Ruby on Rails迁移脚本中创建一个专栏.最好的方法是什么?还有一种方法可以索引表中的列吗?

我想unique在数据库中强制执行列,而不是仅使用:validate_uniqueness_of.

ndp*_*ndp 658

简短的回答:

add_index :table_name, :column_name, unique: true
Run Code Online (Sandbox Code Playgroud)

要将多个列索引在一起,可以传递一组列名而不是一个列名,

add_index :table_name, [:column_name_a, :column_name_b], unique: true
Run Code Online (Sandbox Code Playgroud)

对于更精细的控制,有一个execute执行直接SQL 的" "方法.

而已!

如果您这样做是为了替代常规的旧模型验证,只需检查它是如何工作的.我不确定向用户报告的错误是否会很好.你可以随时做到这两点.

  • +1表示继续使用validates_uniqueness_of.对于单个索引查询的成本,使用此方法的错误处理更清晰我建议他同时执行这两个操作 (36认同)
  • 如果你得到"索引名称......太长",你可以在`add_index`方法中添加`,:name =>"whatever",以缩短名称. (5认同)
  • 我试过了,好像不行!我可以插入两条带有我定义为唯一的column_name 的记录!我正在使用 Rails 2.3.4 和 MySql 有什么想法吗? (2认同)

d.d*_*lov 124

rails生成迁移add_index_to_table_name column_name:uniq

要么

rails生成迁移add_column_name_to_table_name column_name:string:uniq:index

生成

class AddIndexToModerators < ActiveRecord::Migration
  def change
    add_column :moderators, :username, :string
    add_index :moderators, :username, unique: true
  end
end
Run Code Online (Sandbox Code Playgroud)

如果要向现有列添加索引,请删除或注释该add_column行,或进行检查

add_column :moderators, :username, :string unless column_exists? :moderators, :username
Run Code Online (Sandbox Code Playgroud)

  • 我赞成这个,因为我想要命令行表单.但即使我指定`add_index ...`而不是`add_column ...`,它添加列也很愚蠢. (5认同)

Ste*_*ssi 42

由于尚未提及但回答了我在找到此页面时遇到的问题,您还可以指定索引在通过t.references或添加时应该是唯一的t.belongs_to:

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

  # other columns...
end
Run Code Online (Sandbox Code Playgroud)

(截至至少Rails 4.2.7)


Pio*_*ioz 27

如果要创建新表,可以使用内联快捷方式:

  def change
    create_table :posts do |t|
      t.string :title, null: false, index: { unique: true }
      t.timestamps
    end
  end
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您可以跳过 null 定义,即: `t.string :title, index: { unique: true }` (3认同)

小智 13

我正在使用Rails 5,上面的答案很有用; 这是另一种对我有用的方法(表名是:people和列名:email_address)

class AddIndexToEmailAddress < ActiveRecord::Migration[5.0]
  def change
    change_table :people do |t|
      t.index :email_address, unique: true
    end
  end
end
Run Code Online (Sandbox Code Playgroud)