【问题标题】:How do I create a unique index within a Rails create table migration?如何在 Rails 创建表迁移中创建唯一索引?
【发布时间】:2018-01-31 05:39:36
【问题描述】:

我正在使用 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 语句中创建唯一索引的正确方法是什么?

【问题讨论】:

  • user_id 列是否保留在 user_notifications 表中?检查UserNotification.column_names
  • 我不明白你的问题。我在“create table”下面有这个“t.references:users, index: true, on_delete::cascade”,所以不应该创建一个“user_id”列吗?
  • 当我运行上述迁移时,它失败并且没有创建 user_notifications 表。我看到语句“create_table(:user_notifications)”,然后是“rake aborted!StandardError:发生错误,这个和所有以后的迁移都取消了:”,然后是我上面发布的错误。

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


【解决方案1】:

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

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

解决方案:

只需将其更改为t.references :usert.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

【讨论】:

    【解决方案2】:

    尝试提取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
    

    【讨论】:

    • 您是说创建表并在表创建块中包含唯一索引定义是不可能的吗?
    猜你喜欢
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    相关资源
    最近更新 更多