How do I make a column unique and index it in a Ruby on Rails migration?
我想在Ruby on Rails迁移脚本中创建一个列
我想在数据库中强制执行
简短的回答:
1 | add_index :table_name, :column_name, unique: true |
要将多个列索引在一起,可以传递一组列名而不是一个列名,
1 | add_index :table_name, [:column_name_a, :column_name_b], unique: true |
对于更精细的控制,有一个执行直接SQL的"
而已!
如果您这样做是为了替代常规的旧模型验证,只需检查它是如何工作的。我不确定向用户报告的错误是否会很好。你可以随时做到这两点。
rails generate migration add_index_to_table_name column_name:uniq
要么
rails generate migration add_column_name_to_table_name column_name:string:uniq:index
生成
1 2 3 4 5 6 | class AddIndexToModerators < ActiveRecord::Migration def change add_column :moderators, :username, :string add_index :moderators, :username, unique: true end end |
如果要向现有列添加索引,请删除或注释
1 | add_column :moderators, :username, :string unless column_exists? :moderators, :username |
由于尚未提及但回答了我在找到此页面时遇到的问题,您还可以指定索引在通过
1 2 3 4 5 | create_table :accounts do |t| t.references :user, index: { unique: true } # or t.belongs_to # other columns... end |
(截至至少Rails
如果要创建新表,可以使用内联快捷方式:
1 2 3 4 5 6 | def change create_table :posts do |t| t.string :title, null: false, index: { unique: true } t.timestamps end end |
我正在使用Rails 5,上面的答案很有用;这是另一种对我有用的方法(表名是
1 2 3 4 5 6 7 | class AddIndexToEmailAddress < ActiveRecord::Migration[5.0] def change change_table :people do |t| t.index :email_address, unique: true end end end |
1 | add_index :table_name, :column_name, unique: true |
要将多个列索引在一起,可以传递一组列名而不是一个列名。
如果您错过了向DB列添加唯一,只需在模型中添加此验证以检查该字段是否唯一:
1 2 3 | class Person < ActiveRecord::Base validates_uniqueness_of :user_name end |
请参考这里
以上仅供测试之用,请按@Nate建议更改DB列添加索引
有关更多信息,请参阅索引
您可能希望为唯一键添加名称,因为rails的默认unique_key名称可能太长,DB可能会抛出错误。
要为索引添加名称,只需使用
迁移查询可能看起来像这样 -
更多信息 - http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index