我想在Ruby on Rails迁移脚本中创建一个独特的专栏。最好的方法是什么?还有一种方法可以索引表中的列吗?
我希望在数据库中强制惟一的列,而不是仅仅使用:validate_uniqueness_of。
我想在Ruby on Rails迁移脚本中创建一个独特的专栏。最好的方法是什么?还有一种方法可以索引表中的列吗?
我希望在数据库中强制惟一的列,而不是仅仅使用:validate_uniqueness_of。
旧版本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
or
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],唯一的:true,名称:'my_custom_index_name'
更多信息- http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index
因为这还没有被提到,但回答了我找到这个页面时的问题,你也可以指定一个索引应该是唯一的,当通过t.references或t.belongs_to添加它时:
create_table :accounts do |t|
t.references :user, index: { unique: true } # or t.belongs_to
# other columns...
end
(至少Rails 4.2.7)
如果你正在创建一个新表,你可以使用内联快捷方式:
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列来添加索引
请参考此索引以获得更多信息