我可以创建一个 ID 从 0 而不是 1 自动递增的 Rails 模型吗?如何?有什么陷阱吗?我在这里检查过,似乎我不能:
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001911
如果,看起来,我不能,有什么理由我不能或不应该手动为这个类的第一个实例分配一个 ID 0?如果我这样做了,Rails 会自动为下一个创建的实例分配一个 ID 1 吗?
我可以创建一个 ID 从 0 而不是 1 自动递增的 Rails 模型吗?如何?有什么陷阱吗?我在这里检查过,似乎我不能:
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#M001911
如果,看起来,我不能,有什么理由我不能或不应该手动为这个类的第一个实例分配一个 ID 0?如果我这样做了,Rails 会自动为下一个创建的实例分配一个 ID 1 吗?
为什么你需要这样做?在 Rails 模型中,对象 id 代表数据库中的唯一 id,它永远不能为 0(我说的是 mysql,也许 postgres 中的序列和序列有例外)。
ActiveRecord 的工作原理是每个表都有一个在应用程序域中没有意义的主键列。这(部分)是您不必在迁移中定义id
列的原因。create_table
列名(和类型)可以更改,主要是为了适应遗留模式,多列主键根本难以实现。
在您开始将域重要性归因于 id 时,您开始打破常规,我强烈建议您创建另一个字段/属性/成员变量/列/what-have-you 持有该信息。让 id 成为键。
In the use-case you describe, there's no reason that your controller shouldn't identify the special case where params[:id] == '0'
and deal with it appropriately, switching to the "project part", which you identify in some way other than by id
. Since you probably want each project to start from 0, I'd guess you'd add something like seq
and use that instead of id
in your routes, that way your params keys make more sense. Keep the current highest seq
value in the project, so it knows what number to assign when a new part is created. Deletions and insertions (assuming sequence matters) are entirely up to you...
对于 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 的位置很重要。