Rails 迁移 - 添加唯一索引以允许跳过空值

Rails migration - add unique index allowing skipping null values

我想将唯一约束添加到现有 table psql

中的列 name

创建 table (PostgreSQL) :

class CreateRequests < ActiveRecord::Migration
  def change
    create_table :requests do |t|
      t.integer :user_id
      t.string :name
      t.string :address
      t.timestamps null: true
    end
    add_index :requests, :user_id
  end
end

所以我在模型中添加了验证唯一性

class Request < ModelBase
  belongs_to :user
  validates :user, presence: true
  validates :name, uniqueness: true, allow_blank: true
  ...

和这样的迁移:

def change
    add_index :user_requests, :name, unique: true
end

但我注意到在某些情况下名称可以为空我可以 add_index 条件是 :name 为空/不为空吗?

编辑:是的,我希望那些空值保留在数据库中(我不需要修改过去的请求)。我认为我需要编辑迁移以更准确地反映数据库的实际状态。

还添加presence: true 喜欢

validates :name, uniqueness: true, presence: true

您可以在迁移中添加默认值,例如

class AddDefaultToRequests < ActiveRecord::Migration
  def up
    change_column :requests, :name, default: ''
  end

  def down
    change_column :requests, :name
  end
end

确保唯一性的正确格式

validates :name, presence: true, uniqueness: {case_sensitive: false},format: { without: /\s/,message: 'is invalid (spaces are not allowed)'}

您可以尝试验证 here

validates :name, presence: true, uniqueness: true,

其中,presence: true 将验证是否为空,uniqueness: true 将验证用户的唯一名称。

使用以下内容

validates :name, uniqueness: true, if: 'name.present?'

对于索引可能是你尝试

add_index :user_requests, :name, unique: true, where: 'name IS NOT NULL'

没有人回答所以我添加我的解决方案 迁移应如下所示:

def change
    add_index :user_requests, :name, unique: true, where: 'name IS NOT NULL'
end

(验证仍然: validates :name, uniqueness: true, allow_blank: true)