2010-01-15 10 views
12

Tengo un modelo de 'Cuenta' en Rails con su correspondiente tabla de 'cuentas' en la base de datos. Si limpie la base de datos y empiezo de nuevo, el campo 'account_id' siempre comenzará en 1 y contará desde allí. Me gustaría cambiar el número inicial, de modo que, cuando se crea la primera cuenta en una nueva base de datos, el 'account_id' sea, digamos, 1000. ¿Hay alguna manera de hacerlo en Rails, o necesito una base de datos especializada? ¿código SQL dependiente?Cambiar el número de identificación de inicio

En aras de la ilustración, aquí es una versión simplificada de la mesa de mi 'cuentas':

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 

Respuesta

10

Tendrá que hacer un poco de base de datos SQL dependiente especializada para conseguir esta funcionalidad.

Si estás usando MySQL, puede añadir el siguiente código a su migración después del código create_table:

execute("ALTER TABLE tbl AUTO_INCREMENT = 1000") 
+0

Gracias, Peter! Esto definitivamente ayudará. –

12

para PostgreSQL:

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

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

+8

Y en caso de que la gente no sepa (no lo estaba), para ejecutar el comando en la consola, ejecute ActiveRecord :: Base.connection.execute ("... – LikeMaBell

+0

Ese comando no funcionó para mí. Pero esto lo hizo: 'ALTER SEQUENCE accounts_id_seq RESTART 10000;' – jmccartie

5

para SQLite

secuencias se almacenan en la tabla sqlite_sequence (nombre, ss)

  • Comprobar primero si la secuencia ya existe?

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

si sequence.empty?

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

demás

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

2

Otro concepto podría ser posible usar simplemente una variable start_at en su archivo de modelo?

Tal como definir un número base, tal como start_at = 53131 y luego ... Hacer al método de acceso (podría llamarlo "clave") que se suma el número de start_at con propiedades de identificación de su base de datos antes de devolverlo.

Y podría hacer un método de escritura de atrs que sustraiga el start_at antes de guardar la clave, que incluso puede no ser necesario según su implementación.

Ejemplo de pseudo-código tan desnudo conmigo ...

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 

No está seguro de lo práctico que es o si sería incluso trabajar al 100% pero al menos no tendría que modificar la base de datos de manejarlo

+0

No recomendaría este enfoque, aunque funcionaría, cuando mires tu base de datos en un sistema que no sea tu principal, tu ID estaría equivocada. Por ejemplo, si usted conecta su base de datos a un software de análisis, mostraría una identificación incorrecta. – triunenature

2

un rubí puro, el enfoque de base de datos independiente podría ser:

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

Al crear una gran cantidad de registros a la vez, esto no puede llevar a cabo tan bien sin embargo.

0

en SQL Server:

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

En mi caso, el entorno de desarrollo y el entorno de producción están utilizando diferentes tipos de base de datos.

Este bloque de código se ejecutará la ejecución correspondiente a accordin tipo DB - sólo hay que poner en la migración relevante:

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 
Cuestiones relacionadas