指定将在迁移内引用哪个外键表

时间:2016-03-26 21:01:13

标签: ruby-on-rails ruby database postgresql foreign-keys

我正在开发使用PostgreSQL作为数据库的Ruby On Rails应用程序,我遇到了一个问题。

这是我的Questions表格(schema.rb):

create_table "questions", primary_key: "hashid", force: :cascade do |t|
  t.string   "title"
  t.text     "body"
  t.datetime "created_at", null: false
  t.datetime "updated_at", null: false
end

add_index "questions", ["hashid"], name: "index_questions_on_hashid", unique: true, using: :btree

使用hashid字段(字符串)而不是默认的数字id字段。

以下是我对QuestionsComments表的迁移:

# Questions migration
class CreateQuestions < ActiveRecord::Migration
  def change
    create_table :questions, id: false do |t|
      t.text :hashid, primary_key: true
      t.string :title
      t.text :body

      t.timestamps null: false
    end

    add_index :questions, :hashid, unique: true
  end
end


# Comments migration
class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.text :body
      t.references :question, foreign_key: :hashid

      t.timestamps null: false
    end
  end
end

我想在我的应用中将CommentsQuestions相关联,并相应地使用belongs_tohas_many关系,但默认t.references :question正试图通过使用目标表中的id列。

以下是迁移错误消息:

== 20160326185658 CreateComments: migrating ===================================
-- create_table(:comments)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedColumn: ERROR:  column "id" referenced in foreign key constraint does not exist
: ALTER TABLE "comments" ADD CONSTRAINT "comments_question_id_fk"    FOREIGN KEY ("question_id") REFERENCES "questions"(id)

如何通过使用id以外的字段来关联?就我而言,它是hashid

1 个答案:

答案 0 :(得分:1)

即使列包含随机生成的字符串,我仍希望仍然命名主键列id

要在数据库中创建字符串id列,请使用以下迁移:

create_table :questions, id: false do |t|
  # primary key should not be nil, limit to improve index speed
  t.string :id, limit: 36, primary: true, null: false
  # other columns ...
end

在您的模型中,确保创建id

class Question < ActiveRecord::Base
  before_validation :generate_id

private
  def generate_id
    SecureRandom:uuid
  end
end

当您已经使用Rails 5时,您可能只想使用has_secure_token :id而不是before_validation回调和generate_id方法。