Rails在id字段上重置种子的方法

Tre*_*oke 41 sql database ruby-on-rails

我找到了这个问题的"纯SQL"答案.在Rails中,有没有办法重置特定表的id字段?
我为什么要这样做?因为我有不断移动数据的表 - 很少超过100行,但总是不同.它现在高达25k,而且没有任何意义.我打算使用Rails应用程序内部的调度程序(rufus-scheduler)来每月运行id字段重置.

hgm*_*mnz 121

您从未提及您正在使用的DBMS.如果这是postgreSQL,ActiveRecord postgres适配器有一个reset_pk_sequences!你可以使用的方法:

ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
Run Code Online (Sandbox Code Playgroud)

  • Rails使用`Class.table_name`可以改变表名,这可以使它更好.谢谢! (15认同)

kik*_*ito 56

我提出了一个基于hgimenez的答案和另一个答案的解决方案.

由于我通常使用Sqlite或PostgreSQL,我只为那些开发; 但是,将它扩展到MySQL,应该不会太麻烦.

把它放在lib /里面并在初始化器上需要它:

# lib/active_record/add_reset_pk_sequence_to_base.rb
module ActiveRecord
  class Base
    def self.reset_pk_sequence
      case ActiveRecord::Base.connection.adapter_name
      when 'SQLite'
        new_max = maximum(primary_key) || 0
        update_seq_sql = "update sqlite_sequence set seq = #{new_max} where name = '#{table_name}';"
        ActiveRecord::Base.connection.execute(update_seq_sql)
      when 'PostgreSQL'
        ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
      else
        raise "Task not implemented for this DB adapter"
      end
    end     
  end
end
Run Code Online (Sandbox Code Playgroud)

用法:

Client.count # 10
Client.destroy_all
Client.reset_pk_sequence
Client.create(:name => 'Peter') # this client will have id=1
Run Code Online (Sandbox Code Playgroud)

编辑:由于最常见的情况是你想要这样做是在清理数据库表后,我建议看看database_cleaner.它自动处理ID重置.您可以告诉它删除所选的表,如下所示:

DatabaseCleaner.clean_with(:truncation, :only => %w[clients employees])
Run Code Online (Sandbox Code Playgroud)

  • 如果你是我这样的Rails的新手,[这篇博客文章](http://blog.chrisblunt.com/rails-3-how-to-autoload-and-autorequire-your-custom-library-code/)帮助我在初始化程序中设置此代码. (2认同)

cwn*_*nja 5

我假设你不关心数据:

def self.truncate!
  connection.execute("truncate table #{quoted_table_name}")
end
Run Code Online (Sandbox Code Playgroud)

或者,如果你这样做,但不是太多(有一段时间数据只存在于内存中):

def self.truncate_preserving_data!
  data = all.map(&:clone).each{|r| raise "Record would not be able to be saved" unless r.valid? }
  connection.execute("truncate table #{quoted_table_name}")
  data.each(&:save)
end
Run Code Online (Sandbox Code Playgroud)

这将给出具有相同属性的新记录,但id从1开始.

belongs_to这张桌子上的任何东西都会变得棘手.