如何在Rails创建表迁移中创建唯一索引?

时间:2017-08-22 19:59:28

标签: ruby-on-rails postgresql migration rake ruby-on-rails-5

我使用的是Rails 5和PostgreSQL 9.5。如何在表格中创建唯一索引?我想从两列中创建唯一索引,这两列本身就是对其他表的引用。所以我试过

class CreateUserNotificationsTable < ActiveRecord::Migration[5.0]
  def change
    create_table :user_notifications do |t|
      t.references :users, index: true, on_delete: :cascade
      t.references :crypto_currencies, index: true, on_delete: :cascade
      t.integer  "price",      null: false
      t.boolean "buy",      null: false
      t.index [:user_id, :crypto_currency_id], unique: true
    end
  end
end

但我收到了错误

PG::UndefinedColumn: ERROR:  column "user_id" does not exist
: CREATE UNIQUE INDEX  "index_user_notifications_on_user_id_and_crypto_currency_id" ON "user_notifications"  ("user_id", "crypto_currency_id")
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `async_exec'
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.4/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `block in execute'
/Users/davea/.rvm/gems/ruby-2.4.0/gems/activerecord-5.0.4/lib/active_record/connection_adapters/abstract_adapter.rb:590:in `block in log'

在create table语句中创建唯一索引的正确方法是什么?

3 个答案:

答案 0 :(得分:8)

  

PG :: UndefinedColumn:错误:列“user_id”不存在

问题是t.references :users创建了一个名为users_id而不是user_id的列,因此无法使用t.index [:user_id, :crypto_currency_id], unique: true创建索引,因为列user_id不是创建导致该错误。

<强>解决方案:

只需将其更改为t.references :user即可。同样适用于t.references :crypto_currencies

class CreateUserNotificationsTable < ActiveRecord::Migration[5.0]
  def change
    create_table :user_notifications do |t|
      t.references :user, index: true, on_delete: :cascade
      t.references :crypto_currency, index: true, on_delete: :cascade
      t.integer  "price",      null: false
      t.boolean "buy",      null: false
      t.index [:user_id, :crypto_currency_id], unique: true
    end
  end
end

答案 1 :(得分:0)

尝试提取create_table方法的索引,例如:

class CreateUserNotificationsTable < ActiveRecord::Migration[5.0]
  def change
    create_table :user_notifications do |t|
      t.references :users, index: true, on_delete: :cascade
      t.references :crypto_currencies, index: true, on_delete: :cascade
      t.integer  "price",      null: false
      t.boolean "buy",      null: false
    end

    add_index :user_notifications, [:user_id, :crypto_currencies_id], unique: true
  end
end

答案 2 :(得分:-3)

索引名称应该是复数形式的ID,因此您的迁移应该是这样的:

class CreateUserNotificationsTable < ActiveRecord::Migration[5.0]
  def change
    create_table :user_notifications do |t|
      t.references :users, index: true, on_delete: :cascade
      t.references :crypto_currencies, index: true, on_delete: :cascade
      t.integer  "price",      null: false
      t.boolean "buy",      null: false
      # users_id instead of user_id
      t.index [:users_id, :crypto_currencies_id], unique: true
    end
  end
end