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



我正在使用一个现有的rails应用程序,使用postgresql。它的schema.rb文件对许多表(但不是所有表)都有id: :serial

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

当我运行rails db:migrate:reset时,id: :serial将被删除。我们都使用相同版本的postgres,但操作系统不同。我还没有详尽地测试过机器之间的行为,但我认为机器之间是有区别的。

rails版本与项目启动时相同。

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

是什么原因导致此选项在我的环境中被删除?

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

  • https://github.com/rails/rails/blob/b2eb1d1c55a59fee1e6c4cba7030d8ceb524267c/activerecord/lib/active_record/connection_adapters/postgresql/column.rb#L15-L21
  • https://github.com/rails/rails/blob/b2eb1d1c55a59fee1e6c4cba7030d8ceb524267c/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb#L26-L42

更新

  • 我刚刚在同事的机器上尝试了rails db:migrate:reset,但我错了!它们的环境也去除了CCD_ 5
  • 我仔细查看了一位同事最近的迁移,最近的迁移也没有在schema.rb中创建id: :serial

当您运行rails db:migrate:reset而不是rails db:reset时,数据库模式不是从schema.rb加载的,而是从所有迁移中重建的。在迁移和模式文件中,您不需要指定id字段,默认情况下会提供一个字段。然而,从Rails 5.1开始,MySQL的id字段的默认大小从INT增加到了BIGINT,PostgreSQL的id字段从SERIAL增加到BIGSERIAL。因此,您的迁移schema.rb和数据库中的实际模式之间可能存在一些交互,这导致id字段在某些情况下被视为默认字段(并被省略),而在其他情况下被显式指定,只是由于默认大小的变化。如果不查看所有相关文件,很难猜测问题的根源。

答案只是rails 5.0与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)

相关内容

  • 没有找到相关文章

最新更新