我在Rails中有一个“帐户”模型,在数据库中有相应的“帐户”表。如果我擦除数据库并重新开始,'account_id'字段将始终从1开始并从那里开始计数。我想更改起始编号,这样,当在新数据库中创建第一个帐户时,'account_id'就是1000.有没有办法在Rails中执行此操作,或者我是否需要专门的数据库依赖SQL代码?
为了便于说明,这里是我的“帐户”表的简化版本:
create_table "accounts", :force => true do |t|
t.string "email", :null => false
t.string "crypted_password", :null => false
t.string "name", :null => false
t.boolean "email_verified", :default => false
end
答案 0 :(得分:14)
对于PostgreSQL:
execute("ALTER SEQUENCE accounts_id_seq START with 1000 RESTART;")
请参阅https://www.postgresql.org/docs/current/static/sql-altersequence.html
答案 1 :(得分:10)
您需要执行一些专门的数据库相关SQL才能获得此功能。
如果您使用的是MySQL,则可以在create_table
代码后向迁移中添加以下代码:
execute("ALTER TABLE tbl AUTO_INCREMENT = 1000")
答案 2 :(得分:5)
对于sqlite
序列存储在表sqlite_sequence
(name,seq)
首先检查序列是否已存在?
select name,seq from sqlite_sequence where name = 'accounts'
if sequence.empty?
insert into sqlite_sequence(name,seq) values('accounts', 1000);
否则
update sqlite_sequence set seq = 1000 where name = 'accounts';
答案 3 :(得分:2)
另一个可能的概念可能是在模型文件中使用start_at变量吗?
例如定义start_at = 53131
等基数,然后......
创建一个访问器方法(可以称之为“密钥”),在返回之前将start_at
编号添加到数据库的真实ID中。
你可以制作一个attr writer方法,在保存密钥之前减去start_at
,根据你的实现,这可能根本不需要。
伪代码中的示例请耐心等待。
class FakeModel
attr_accessible :name
start_at = 53121
def self.find_by_key(key)
find_by_id(key-start_at))
end
def key
(self.id+start_at)
end
end
不确定这是多么实用,或者它是否能100%正常工作,但至少你不必修改数据库来处理它。
答案 4 :(得分:2)
纯Ruby,独立于数据库的方法可能是:
class MyModel
before_create do
self.id = [1000, self.class.maximum(:id)+1].max if self.id.nil?
end
end
当你一次创建大量记录时,这可能表现不佳。
答案 5 :(得分:0)
:
execute('DBCC CHECKIDENT (accounts, reseed, 1000)')
就我而言,开发环境和生产环境使用不同类型的数据库。
此代码块将按照DB类型运行相关执行 - 只需将其置于相关的迁移中:
puts 'Migration trys to set initial account ID to adapter:' + ActiveRecord::Base.connection.adapter_name
case ActiveRecord::Base.connection.adapter_name
when 'MySQL'
execute('ALTER TABLE accounts AUTO_INCREMENT = 1000')
when 'SQLServer'
execute('DBCC CHECKIDENT (accounts, reseed, 1000)')
when 'SQLite'
begin
execute('insert into sqlite_sequence(name,seq) values(\'accounts\', 1000);')
rescue
puts 'insert error... updating'
end
execute('update sqlite_sequence set seq = 1000 where name = \'accounts\';')
else
puts "cant recognize the database"
end