Change starting id number

前端 未结 6 911
灰色年华
灰色年华 2021-02-05 10:53

I have an \'Account\' model in Rails with its corresponding \'accounts\' table in the database. If I wipe the database and start over, the \'account_id\' field will always star

相关标签:
6条回答
  • 2021-02-05 11:31

    You'll need to do some specialized database-dependent SQL to get this functionality.

    If you're using MySQL, you can add the following code to your migration after the create_table code:

    execute("ALTER TABLE tbl AUTO_INCREMENT = 1000")
    
    0 讨论(0)
  • 2021-02-05 11:31

    For sqlite

    sequences are stored in the table sqlite_sequence (name,seq)

    • Check first if the sequence already exists?

      select name,seq from sqlite_sequence where name = 'accounts'

    if sequence.empty?

    insert into sqlite_sequence(name,seq) values('accounts', 1000);

    else

    update sqlite_sequence set seq = 1000 where name = 'accounts';

    0 讨论(0)
  • 2021-02-05 11:32

    A pure Ruby, database-independent approach could be:

    class MyModel
      before_create do
        self.id = [1000, (self.class.maximum(:id) || 0) + 1].max if self.id.nil?
      end
    end
    

    When you're creating lots of records at once, this may not perform so well though.

    0 讨论(0)
  • 2021-02-05 11:37

    in SQL Server:

    execute('DBCC CHECKIDENT (accounts, reseed, 1000)')
    

    In my case, the development environment and the production environment are using different type of database.

    This code block will run the relevant execution accordin to DB type - just put it in the relevant migration:

    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
    
    0 讨论(0)
  • 2021-02-05 11:46

    for PostgreSQL:

    execute("ALTER SEQUENCE accounts_id_seq START with 1000 RESTART;")
    

    see https://www.postgresql.org/docs/current/static/sql-altersequence.html

    0 讨论(0)
  • 2021-02-05 11:48

    Another possible concept might be to simply use a start_at variable in your model file?

    Such as define a base number such as start_at = 53131 and then... Make an accessor method (could call it "key") which adds your start_at number to your database's real ID before returning it.

    And you could make a attr writer method that subtracts the start_at before saving the key, that may not even be necessary depending on your implementation.

    Example in pseudo-code so bear with me.

    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
    

    Not sure how practical this is or if it would even work 100% but at least you wouldn't have to modify the database to handle it.

    0 讨论(0)
提交回复
热议问题