繁体   English   中英

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

[英]What determines if rails includes id: :serial in a table definition?

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

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

当我运行rails db:migrate:resetid: :serial被删除。 我们都是相同版本的postgres,但不同的操作系统。 我没有详尽地测试机器之间的行为,但我认为机器之间存在差异。

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

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

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

这里有一些可能相关的代码:

更新

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

答案只是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 serial指定

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)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM