如何在Ruby on Rails迁移中使列唯一并为其建立索引?

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

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

270113 次浏览

旧版本Rails的简短回答(参见Rails 4+的其他答案):

add_index :table_name, :column_name, unique: true

要一起索引多个列,需要传递一个列名数组,而不是一个列名,

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

如果你得到“index name…”,您可以在add_index方法中添加name: "whatever"以使名称更短。

对于细粒度控制,有一个“execute”方法直接执行SQL。

就是这样!

如果您这样做是为了代替常规的旧模型验证,请检查它是如何工作的。如果没有模型级验证,向用户报告错误可能就不会那么好。你可以两者兼顾。

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

如果您正在向现有列添加索引,请删除或注释add_column行,或放入复选

add_column :moderators, :username, :string unless column_exists? :moderators, :username

我使用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

您可能希望为唯一键添加name,因为rails默认的unique_key名称可能太长,DB可能会抛出错误。

要为索引添加名称,只需使用name:选项。 迁移查询可能看起来像这样-

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

更多信息- http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

因为这还没有被提到,但回答了我找到这个页面时的问题,你也可以指定索引在通过t.referencest.belongs_to添加时应该是唯一的:

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


# other columns...
end

(至少Rails 4.2.7)

add_index :table_name, :column_name, unique: true

若要一起索引多个列,则传递一个列名数组,而不是单个列名。

如果你正在创建一个新表,你可以使用内联快捷方式:

  def change
create_table :posts do |t|
t.string :title, null: false, index: { unique: true }
t.timestamps
end
end

如果你错过了添加唯一的DB列,只需在模型中添加这个验证来检查字段是否唯一:

class Person < ActiveRecord::Base
validates_uniqueness_of :user_name
end

参考此处 以上仅用于测试目的,请根据@Nate的建议通过更改DB列来添加指数

更多信息请参考与指数