【问题标题】:Can I create a Rails model where the ID auto-increments from 0, not 1?我可以创建一个 ID 从 0 而不是 1 自动递增的 Rails 模型吗?
【发布时间】:2009-09-20 06:11:15
【问题描述】:

我可以创建一个 ID 从 0 而不是 1 自动递增的 Rails 模型吗?如何?有什么陷阱吗?我在这里查了一下,好像不行:

http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001911

如果,看起来,我不能,有什么理由我不能或不应该手动为这个类的第一个实例分配一个 ID 0?如果这样做,Rails 会自动为下一个创建的实例分配 ID 1 吗?

【问题讨论】:

    标签: ruby-on-rails ruby model auto-increment


    【解决方案1】:

    您为什么需要这样做?在 Rails 模型中,对象 id 代表数据库中的唯一 id,它永远不能为 0(我说的是 mysql,也许 postgres 中的序列和序列有例外)。

    【讨论】:

    • 谢谢艾曼塔斯。我以前很怕那个。你问我为什么需要这样做?因为模型是“part”,belongs_to“project”。第一部分是包含整个项目的部分。当用户创建项目时,软件会在用户创建自己的任何较小部分之前创建它。如果这部分在浏览器的位置栏中向用户显示为“/part/0”,并且如果用户只看到过“/part/2”(如果他们定义了 2 个部分),那么从用户体验的角度来看,这将是一件好事自己的。
    • 您可以为每个部分使用单独的计数器,而不是为此使用主键。除此之外,我会将第 0 部分(对于整个项目)保留在项目对象本身中。
    • 我代表 mysql,auto_increment 列的默认值为 0,因此第一条记录变为 0 + 1 = 1,要获得“第一条记录”值为 0,您必须默认 auto_increment值为 -1 。所以 -1 + 1 = 0 ,我怀疑这是否可能。
    • 这仅适用于第一个项目。当有人创建第二个项目时,第 0 部分将是 project1.parts.count + 1。这不是您想要的。
    • Anand +1 获取默认的 auto_increment 提示。不知道。)
    【解决方案2】:

    ActiveRecord 的工作原理是每个表都有一个在应用程序域中没有意义的主键列。这(部分)是您不必在 create_table 迁移中定义 id 列的原因。列名(和类型)可以更改,主要是为了适应遗留模式,而且多列主键根本难以实现。

    当您开始将域重要性归因于 id 时,您开始打破惯例,我强烈建议您创建另一个字段/属性/成员变量/列/what-have-您持有该信息。让 id 成为键。

    在您描述的用例中,您的控制器没有理由不识别 params[:id] == '0' 的特殊情况并适当处理它,切换到您以其他方式识别的“项目部分”通过id。由于您可能希望每个项目从 0 开始,我猜您会添加类似 seq 的内容,并在您的路线中使用它而不是 id,这样您的 params 键更有意义。在项目中保留当前最高的seq 值,这样它就知道在创建新部件时要分配什么编号。删除和插入(假设顺序很重要)完全取决于您...

    【讨论】:

      【解决方案3】:

      对于 postgres,您可能想看看手动创建表,例如

      class MigrationName < ActiveRecord::Migration
        def self.up
          execute <<EOF
      
      create sequence foos_id_seq start 0 increment 1 no cycle;
      create table foos (
        id       integer not null default nextval('foos_id_seq'),
        ...
        primary key(id)
      );
      EOF
        end
      
        def self.down
          execute <<EOF
      drop table foos;
      drop sequence foos_id_seq;
      EOF
        end
      end
      

      注意,EOF 的位置很重要。

      【讨论】:

        猜你喜欢
        • 2013-01-27
        • 2012-05-31
        • 2017-11-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-26
        • 2021-04-15
        • 2016-01-31
        相关资源
        最近更新 更多