Rails使用uuids迁移create_join_table

iha*_*dez 6 ruby-on-rails rails-activerecord

较新版本的rails允许您指定应使用uuid主键创建表,如下所示:

create_table :foos, id: :uuid do |t|
  # ...
end
Run Code Online (Sandbox Code Playgroud)

哪个好.很长一段时间,rails支持创建连接表,如下所示:

create_join_table :foos, :bars do |t|
  # ...
end
Run Code Online (Sandbox Code Playgroud)

也很棒.除了我的表有uuid主键,并生成整数类型的外键列而不是类型uuid.

查看文档create_join_table,我找不到任何明显的更改列类型.可以create_join_table和uuids 一起使用吗?

或者我是否手动创建了连接表:

create_table :bars_foos, id: false do |t|
  t.uuid :bar_id
  t.uuid :foo_id
end
Run Code Online (Sandbox Code Playgroud)

Ima*_*yne 8

无法使用 uuid 创建连接表。

正如问题中指出的那样,create_table这是唯一的选择。create_join_tables使用 uuid进行模拟的最佳方法是使用create_tables以下命令:

  • 跑步:rails g migration CreateFoosBars bars:references foos:references
  • 该命令将产生以下输出,您需要修改该输出

生成输出

class CreateBarFoos < ActiveRecord::Migration
  def change
    create_table :bars_foos, id: :uuid do |t|
      t.references :bars, foreign_key: true
      t.references :foo, foreign_key: true
    end
  end
end
Run Code Online (Sandbox Code Playgroud)
  • 改变id: uuid=>id: false
  • 添加type: uuid, index: true到参考文献末尾

最终迁移

class CreateBarFoos < ActiveRecord::Migration
  def change
    create_table :bars_foos, id: false do |t|
      t.references :bars, foreign_key: true, type: :uuid, index: true
      t.references :foo, foreign_key: true, type: :uuid, index: true
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

如果 Rails 可以在 中添加对不同 id 类型的额外支持,那就太好了 create_join_table,这甚至可以通过现有的迁移来推断。

在那之前,希望这些步骤能够达到相同的结果。

  • 这是给定版本的 Rails (4.2.x) 的正确答案,@anka 的答案对于版本 5 及更高版本是正确的。 (2认同)

ank*_*nka 7

Rails 5.0你可以使用一个附加选项column_optionscreate_join_table方法来指定ID列的类型.您的迁移将如下所示:

create_join_table :foos, :bars, column_options: {type: :uuid} do |t|
  t.index [:foo_id, :baar_id]
end
Run Code Online (Sandbox Code Playgroud)


iha*_*dez 5

我应该看一下代码......

def create_join_table(table_1, table_2, options = {})
  join_table_name = find_join_table_name(table_1, table_2, options)

  column_options = options.delete(:column_options) || {}
  column_options.reverse_merge!(null: false)

  t1_column, t2_column = [table_1, table_2].map{ |t| t.to_s.singularize.foreign_key }

  create_table(join_table_name, options.merge!(id: false)) do |td|
    td.integer t1_column, column_options
    td.integer t2_column, column_options
    yield td if block_given?
  end
end
Run Code Online (Sandbox Code Playgroud)

列显式创建为整数,无法更改它们.太糟糕了...