【问题标题】:Adding a reference to a non-integer column in rails migration在 Rails 迁移中添加对非整数列的引用
【发布时间】:2020-03-15 17:39:59
【问题描述】:

我今天研究了几个关于这个主题的问题。我知道,我可以在迁移中使用t.references 来添加引用。但是,如果表具有非整数主键,我如何添加对该列的引用?

我有一张这样定义的表

    create_table :sessions, id: false do |t|
      t.string  :session, primary_key: true, limit: 10  

      t.timestamps null: false
    end

如何添加对session 列的引用(名称在这里无关紧要),它是来自另一个表迁移的字符串。我用t.references 进行了测试,但这只是添加了一个整数列。我知道我可以使用add column。但是不直接使用create_table 方法怎么办呢?

重复标志的说明
这个问题被标记为与this question 重复,但实际上并非如此。因为我不是在询问使用非默认非整数主键设置表,因为我已经设置了该表。我问的是从另一个表中引用这种类型的表。

【问题讨论】:

  • @ABMagil 我不认为它是重复的,因为 Anwar 询问 references 对非整数主键 - 而不是主键本身。

标签: ruby-on-rails rails-migrations


【解决方案1】:

您需要使用字符串类型,而不是使用引用帮助器,并添加索引以加快查找速度。如果您的其他模型是“记录”:

rails generate migration AddSessionIdToRecords session:string:index

应该像这样生成迁移:

def change
  add_column :records, :session_id, :string
  add_index :records, :session_id
end

由于您使用非常规命名,您需要指定模型中的主键和关系定义:

class Session < ActiveRecord::Base
  self.primary_key = "session"

  has_many :records, primary_key: "session"
end

class Record < ActiveRecord::Base
  belongs_to :session, primary_key: "session"
end

【讨论】:

  • 我的设置几乎是这样的,但我认为是foreign_key: "session" 而不是primary_key: "session"。你应该检查
  • 你在另一个表上的列命名是什么(“records”)?那是foreign_key,所以如果你把它命名为session,foreign_key就是"session"
  • 重点是我必须使用foreign_key选项,而不是primary_key选项
【解决方案2】:

其实不用在Session&Record类中添加primary_key

def change
  add_column :records, :session_id, :string
  add_index :records, :session_id
  add_foreign_key :records, :sessions, column: :session_id, primary_key: "your_primary_key_name_in_sessions_table"
end

仅此而已。

【讨论】:

  • 我为什么要使用:session_id 作为string
【解决方案3】:

我得出的结论是,如果不使用 rails 4.2 中引入的foreign_key,我无法真正引用另一列,只能按照this answer from eirikir 的建议创建索引。

从 Rails 4.2 开始,我可以像这样使用外键

在会话表迁移

create table :sessions, id: false do |t|
  t.string "session", primary_key: true
  t.timestamp null: false
end

让记录表引用session主键

create table :records do |t|
  t.string "session", null: false
  ..
  .. # other attributes
end

add_index :records, :session
add_foreign_key :records, :sessions, column: :session, primary_key: :session

在这里,column: 选项修复了我要在哪一列上创建外键,primary_key: 选项修复了引用表的主键,这里是session

【讨论】:

    【解决方案4】:

    由于 rails 版本为4.2.7,您可以将type 指定到add_reference 助手中。 假设您有表records,并且您希望在records 中引用sessions。然后您可以执行以下操作:

    add_reference :records, :sessions, type: :string, foreign_key: {to_table: :sessions, primary_key: :session}
    

    【讨论】:

      猜你喜欢
      • 2017-02-17
      • 2014-05-13
      • 1970-01-01
      • 2020-05-21
      • 2014-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-09
      相关资源
      最近更新 更多