2010-01-15 16 views
12

Ho un modello "Account" in Rails con la corrispondente tabella "account" nel database. Se pulisco il database e ricomincia, il campo 'account_id' inizia sempre da 1 e conta da lì. Vorrei cambiare il numero iniziale, in modo che, quando il primo account viene creato in un nuovo database, il 'account_id' è, per esempio, 1000. C'è un modo per farlo in Rails, o ho bisogno di un database specializzato -Dipendente codice SQL?Cambia codice ID iniziale

Per motivi di illustrazione, qui è una versione semplificata del mio tavolo 'conti':

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 

risposta

10

Avrai bisogno di fare un po 'di database SQL-dipendente specializzato per ottenere questa funzionalità.

Se stai usando MySQL, è possibile aggiungere il seguente codice per la migrazione dopo il codice create_table:

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

Grazie, Peter! Questo sicuramente aiuterà. –

12

per PostgreSQL:

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

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

+8

E nel caso in cui le persone non siano a conoscenza (non lo ero), per eseguire il comando nella console, eseguire ActiveRecord :: Base.connection.execute ("... – LikeMaBell

+0

Questo comando non ha funzionato per me. ha fatto: 'ALTER SEQUENCE accounts_id_seq RESTART 10000;' – jmccartie

5

per SQLite

sequenze sono memorizzate nella tabella sqlite_sequence (nome, ss)

  • verificare prima se la sequenza è già esistente?

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

se sequence.empty?

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

altro

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

2

Un altro concetto potrebbe essere possibile usare semplicemente una variabile start_at nel file modello?

Come definire un numero base come start_at = 53131 e poi ... Fai metodo di accesso (potrebbe chiamarla "chiave") che aggiunge il proprio numero start_at al reale ID del proprio database prima di restituirlo.

E si potrebbe creare un metodo attr writer che sottrae lo start_at prima di salvare la chiave, che potrebbe non essere nemmeno necessario a seconda dell'implementazione.

Esempio in pseudo-codice in modo nudo con 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 

Non sono sicuro di come questo è pratico o se avrebbe anche lavorare al 100%, ma almeno non avrebbe dovuto modificare il database di occupatene.

+0

Non consiglierei questo approccio, mentre funzionerebbe, quando stai guardando il tuo database in un sistema diverso da quello principale, i tuoi ID sarebbero tutti sbagliati. Ad esempio, se colleghi il tuo database ad un software di analisi, mostrerebbe l'ID sbagliato. – triunenature

2

A puro Ruby, approccio indipendente dal database potrebbe essere:

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

Quando si sta creando un sacco di record in una sola volta, questo potrebbe non funzionare così bene però.

0

in SQL Server:

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

Nel mio caso, l'ambiente di sviluppo e l'ambiente di produzione stanno usando diversi tipi di database.

Questo blocco di codice verrà eseguito l'esecuzione relativo Accordin di tipo DB - appena messo nella migrazione rilevanti:

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 
Problemi correlati