【问题标题】:Specify which foreign key table will be referred to inside of a migration指定将在迁移中引用哪个外键表
【发布时间】:2016-03-26 21:01:12
【问题描述】:

我正在开发使用 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

我想在我的应用程序中使用belongs_tohas_many 关系将CommentsQuestions 相关联,但默认的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?

【问题讨论】:

  • 为什么要与 Rails 约定作斗争,而不是使用默认名称 id 作为主键?你想达到什么目标?
  • 因为我正在尝试创建类似 youtube 的东西,它的视频 ID 是随机字符串,而不是数字 ID,至少我是这么认为的。这就是为什么我将默认数字 id 更改为随机字符串作为 id
  • 您仍然可以将该列命名为id,即使它包含应用程序生成的随机字符串。如果您选择了其他名称,您将不得不修复许多不同的事情:迁移、类主键定义、路由、查找器...
  • 或者,如果有一种方法可以使用默认数字 id 将记录保存在数据库中,但是用随机字符串重写 URL,我最好还是采用这种方式。但我真的不知道如何实现这一点,这样做是不是一个好主意。
  • 没关系。我已经想通了。我只是在我的Question 中创建额外的字段,然后我将随机字符串分配给字段,然后在我的路由中我添加路由,例如 get 'questions/:my_random_string_field', to: 'questions#show'。

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


【解决方案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 方法。

【讨论】:

    猜你喜欢
    • 2022-11-30
    • 2012-11-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 2011-09-18
    • 2016-10-04
    • 2013-08-27
    • 1970-01-01
    相关资源
    最近更新 更多