Rails auto-assegnando l’ID che esiste già

Creo un nuovo record in questo modo:

truck = Truck.create(:name=>name, :user_id=>2)

Il mio database ha attualmente diverse migliaia di quadro per il camion, ma ho assegnato gli ID a diversi di essi, in un modo che lasciava alcuni ID disponibili. Quindi, quello che sta succedendo è che rails crea oggetti con id = 150 e funziona perfettamente. Ma poi prova a creare un object e assegnarlo id = 151, ma quell’id potrebbe già esistere, quindi vedo questo errore:

ActiveRecord::RecordNotUnique (PG::Error: ERROR: duplicate key value violates unique constraint "companies_pkey" DETAIL: Key (id)=(151) already exists.

E la prossima volta che eseguirò l’azione, assegnerà semplicemente l’id 152, che funzionerà correttamente se quel valore non è già stato preso. Come posso ottenere le rotaie per verificare se un ID esiste già prima di assegnarlo?

Grazie!

MODIFICARE

L’id Truck è ciò che viene duplicato. L’utente esiste già ed è una costante in questo caso. In realtà è un problema ereditario che devo affrontare. Un’opzione, è ricreare il tavolo a lasciare che le rotaie assegnino automaticamente ogni id questa volta. Sto iniziando a pensare che questa potrebbe essere la scelta migliore perché ho qualche altro problema, ma la migrazione per farlo sarebbe molto complicata perché Truck è una chiave straniera in tanti altri tavoli. Ci sarebbe un modo semplice per far sì che le rotaie creino una nuova tabella con gli stessi dati già archiviati in Truck, con ID assegnati automaticamente e mantenendo tutte le relazioni esistenti?

Rails sta probabilmente usando la sequenza PostgreSQL incorporata. L’idea di una sequenza è che viene utilizzata solo una volta.

La soluzione più semplice è impostare la sequenza per la colonna company.id sul valore più alto nella tabella con una query come questa:

 SELECT setval('company_id_seq', (SELECT max(id) FROM company)); 

Sto indovinando il nome della sequenza “company_id_seq”, il nome della tabella “company” e il nome della colonna “id” … per favore sostituiscili con quelli corretti. È ansible ottenere il nome della sequenza con SELECT pg_get_serial_sequence('tablename', 'columname'); o guarda la definizione della tabella con \d tablename .

Una soluzione alternativa consiste nell’override del metodo save () nella class della società per impostare manualmente l’id azienda per le nuove righe prima di salvare.

Ho fatto questo che ha risolto il problema per me.

 ActiveRecord::Base.connection.tables.each do |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) end 

Ho trovato il reset_pk_sequence! da questo thread. http://www.ruby-forum.com/topic/64428

Basato sulla risposta di @Apie.

Puoi creare un’attività ed eseguirla quando ti serve con:

 rake database:correction_seq_id 

Crei attività come questa:

 rails g task database correction_seq_id 

E nel file generato ( lib/tasks/database.rake ) metti:

 namespace :database do desc "Correction of sequences id" task correction_seq_id: :environment do ActiveRecord::Base.connection.tables.each do |t| ActiveRecord::Base.connection.reset_pk_sequence!(t) end end end 

Mi sembra un problema con il database e non un problema con Rails. È ansible che il tuo database abbia una seed di id quadro impropria nella colonna id ? Per provare prova a fare un paio di inserimenti direttamente nel tuo database e vedere se esiste lo stesso comportamento.