是什么决定了rails是否在表定义中包含id::serial?

时间:2019-02-08 18:48:30

标签: ruby-on-rails postgresql rails-migrations

我正在使用postgresql使用现有的Rails应用程序。它的schema.rb文件具有许多(但不是全部)表的id: :serial

create_table "foos", id: :serial, force: :cascade do |t|

当我运行rails db:migrate:reset时,id: :serial被删除。我们都使用相同版本的postgres,但使用不同的操作系统。我尚未详尽测试机器之间的行为,但我认为机器之间存在差异。

rails版本与项目开始时的版本相同。

该项目确实从sqlite3开始。当我切换到该文件并重新生成文件时,行为相同。

什么会导致在我的环境中删除此选项?

以下是一些可能相关的代码:

更新

  • 我刚刚在同事的机器上尝试过rails db:migrate:reset,但我错了!他们的环境也会删除id: :serial
  • 我仔细观察了一位同事最近进行的迁移,最近一次迁移也没有在schema.rb中创建id: :serial

2 个答案:

答案 0 :(得分:4)

当您运行rails db:migrate:reset而不是rails db:reset时,不会从schema.rb加载数据库模式,而是从所有迁移中重建数据库模式。在迁移和模式文件中,您无需指定id字段,默认情况下会提供一个字段。但是,从Rails 5.1开始,对于MySQL,default size of the id field was increasedINTBIGINT;对于PostgreSQL,从SERIALBIGSERIAL。因此,您的迁移schema.rb与数据库中的实际模式之间可能存在某种交互,这导致在某些情况下将id字段视为默认(并省略),而在其他情况下则将其显式指定,默认大小的更改。如果不查看所有相关文件,很难猜测问题的根源。

答案 1 :(得分:4)

答案仅仅是rails 5.0 vs 5.1的迁移。我以前认为该项目始于5.1,所以我没有对此进行测试。但是后来我更深入地研究,发现它从5.0开始,实验表明这就是答案。

5.0,未指定ID

class SerialIdTest < ActiveRecord::Migration[5.0]
  def change
    create_table "test" do |t|
      t.integer "foo_id"
      t.string "foo_role"
    end
  end
end
create_table "test", id: :serial, force: :cascade do |t|
  t.integer "foo_id"
  t.string "foo_role"
end
# \d test
                                   Table "public.test"
      Column      |       Type        |                       Modifiers                       
------------------+-------------------+-------------------------------------------------------
 id               | integer           | not null default nextval('test_id_seq'::regclass)
 foo_id   | integer           | 
 foo_role | character varying | 
Indexes:
    "test_pkey" PRIMARY KEY, btree (id)

5.1,未指定ID

class SerialIdTest < ActiveRecord::Migration[5.1]
  def change
    create_table "test" do |t|
      t.integer "foo_id"
      t.string "foo_role"
    end
  end
end
create_table "test", force: :cascade do |t|
  t.integer "foo_id"
  t.string "foo_role"
end
# \d test
                                   Table "public.test"
      Column      |       Type        |                       Modifiers                       
------------------+-------------------+-------------------------------------------------------
 id               | bigint            | not null default nextval('test_id_seq'::regclass)
 foo_id   | integer           | 
 foo_role | character varying | 
Indexes:
    "test_pkey" PRIMARY KEY, btree (id)

5.1,指定了ID序列

class SerialIdTest < ActiveRecord::Migration[5.1]
  def change
    create_table "test", id: :serial do |t|
      t.integer "foo_id"
      t.string "foo_role"
    end
  end
end
create_table "test", id: :serial, force: :cascade do |t|
  t.integer "foo_id"
  t.string "foo_role"
end
# \d test
                                   Table "public.test"
      Column      |       Type        |                       Modifiers                       
------------------+-------------------+-------------------------------------------------------
 id               | integer           | not null default nextval('test_id_seq'::regclass)
 foo_id   | integer           | 
 foo_role | character varying | 
Indexes:
    "test_pkey" PRIMARY KEY, btree (id)