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

eud*_*nia 12 ruby-on-rails psql

我想向name现有表 psql 中的列添加唯一约束

创建表(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
Run Code Online (Sandbox Code Playgroud)

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

class Request < ModelBase
  belongs_to :user
  validates :user, presence: true
  validates :name, uniqueness: true, allow_blank: true
  ...
Run Code Online (Sandbox Code Playgroud)

和这样的迁移:

def change
    add_index :user_requests, :name, unique: true
end
Run Code Online (Sandbox Code Playgroud)

但我注意到在某些情况下,名称可以为空,我可以在条件:name为空/不为空的情况下添加索引吗?

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

eud*_*nia 17

没有人回答所以我添加我的解决方案迁移应该是这样的:

def change
    add_index :user_requests, :name, unique: true, where: 'name IS NOT NULL'
end
Run Code Online (Sandbox Code Playgroud)

(验证还是: validates :name, uniqueness: true, allow_blank: true

  • Null 和empty 不一样,所以我们可以在索引中添加“(name IS NOT NULL) OR (name != '')”,如下所示: add_index :user_requests, :name, unique: true, where: “(name不为空)或(名称!='')” (2认同)

Sal*_*lil 6

使用以下

validates :name, uniqueness: true, if: 'name.present?'
Run Code Online (Sandbox Code Playgroud)

对于索引,您可能会尝试

add_index :user_requests, :name, unique: true, where: 'name IS NOT NULL'
Run Code Online (Sandbox Code Playgroud)