Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails migration - add unique index allowing skipping null values

I wanted like to add unique constraint to column name in existing table psql

created 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

So I added validation uniqueness in model

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

and migration like this:

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

but I noticed that in some cases name can be empty can I add_index with condition were :name is null / not null?

Edit: yes, I want those empty values to stay in the database (I don't need to modify past request). I think that I need to edit migration to be more accurate to the actual state of db.

like image 384
eudaimonia Avatar asked Jan 05 '18 11:01

eudaimonia


People also ask

What is null false in Rails migration?

The null: false parameter means this column does not allow NULL values. The default: false tells us this column will default to false whenever a value isn't specified. This is nice because we can guarantee this field will always be either true or false now. It can't be null because the database prevents it.

What does db Migrate do in Rails?

A migration means that you move from the current version to a newer version (as is said in the first answer). Using rake db:migrate you can apply any new changes to your schema. But if you want to rollback to a previous migration you can use rake db:rollback to nullify your new changes if they are incorrectly defined.

What is index in Rails migration?

An index is used to speed up the performance of queries on a database. Rails allows us to create index on a database column by means of a migration. By default, the sort order for the index is ascending. But consider the case where we are fetching reports from the database.


2 Answers

No one answer so I'm adding my solution migration should look like that:

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

(validation still: validates :name, uniqueness: true, allow_blank: true)

like image 81
eudaimonia Avatar answered Sep 19 '22 16:09

eudaimonia


Use following

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

For index may be you try

add_index :user_requests, :name, unique: true, where: 'name IS NOT NULL'
like image 45
Salil Avatar answered Sep 18 '22 16:09

Salil