Ho trovato le risposte "SQL puro" a questa domanda. C'è un modo, in Rails, per reimpostare il campo id per una tabella specifica?
Perché voglio farlo? Perché ho tabelle con dati in costante movimento - raramente più di 100 righe, ma sempre diverse. È fino a 25k ora, e non ha proprio senso. Intendo utilizzare uno scheduler interno all'app Rails (rufus-scheduler) per eseguire il reset del campo ID mensilmente o giù di lì.Rails per ripristinare i semi sul campo ID
risposta
Sono uscito con una soluzione basata sulla risposta di hgimenez e this other one.
Poiché di solito lavoro con Sqlite o PostgreSQL, ho sviluppato solo per quelli; ma estendendolo a, diciamo MySQL, non dovrebbe essere troppo fastidioso.
mettere questo dentro lib/e richiedono su un inizializzatore:
# 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
Usage:
Client.count # 10
Client.destroy_all
Client.reset_pk_sequence
Client.create(:name => 'Peter') # this client will have id=1
EDIT: Dal momento che il caso più comune in cui si vuole fare questo è dopo aver eliminato una tabella di database, consiglio di dare un'occhiata a database_cleaner. Gestisce automaticamente il reset dell'ID. Si può dire che per eliminare le tabelle appena selezionate in questo modo:
DatabaseCleaner.clean_with(:truncation, :only => %w[clients employees])
Se non conosci Rails come me, [questo post del blog] (http://blog.chrisblunt.com/rails-3-how-to-autoload-and-autorequire-your-custom -library-code /) mi ha aiutato a impostare questo codice in un inizializzatore. –
Un problema è che questi tipi di campi vengono implementati in modo diverso per diverse sequenze databases-, auto-incrementi, ecc
È sempre possibile eliminare e aggiungere nuovamente la tabella.
No, non c'è niente di simile in Rails. Se hai bisogno di un bel id per mostrare gli utenti, quindi li memorizza in una tabella separata e riutilizzarli.
È intelligente! Non lo sto mostrando all'utente però. Voglio solo evitare di traboccare in 10.000 anni. :-) – Trevoke
Si poteva fare solo in Rails se i _ids vengono impostati dai binari. Finché i _id vengono impostati dal tuo database, non sarai in grado di controllarli senza usare SQL.
Nota a margine: Credo che usando le rotaie per chiamare regolarmente una procedura SQL che azzera o scende e ricrea una sequenza non sarebbe una soluzione puramente SQL, ma non credo che è quello che si sta chiedendo ...
EDIT:
Disclaimer: non so molto su rotaie.
Dal punto di vista SQL, se si dispone di una tabella con colonne id first_name last_name
e di solito insert into table (first_name, last_name) values ('bob', 'smith')
si può semplicemente cambiare le vostre domande a insert into table (id, first_name, last_name) values ([variable set by rails], 'bob', 'smith')
In questo modo, il _id viene impostato da una variabile, invece di essere impostato automaticamente da SQL. A quel punto, le rotaie hanno il controllo completo su ciò che sono le _id (anche se si tratta di un PK è necessario assicurarsi di non utilizzare lo stesso valore mentre è ancora lì).
Se avete intenzione di lasciare l'incarico fino al database, è necessario disporre di rotaie Run (su qualunque tempo di programma) qualcosa come:
DROP SEQUENCE MY_SEQ;
CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1;
a qualsiasi sequenza controlla gli ID per il vostro tavolo. Questo eliminerà la sequenza corrente e ne creerà una nuova. Questo è il modo più semplice che conosco per resettare una sequenza.
Beh, dovrò usare Rails per chiamare regolarmente un'istruzione SQL per ri-seminare, penso :) Per curiosità, come faccio a impostare Rails per _id? – Trevoke
Non hai mai menzionato che DBMS stai usando. Se questo è PostgreSQL, l'adattatore Postgres ActiveRecord ha un metodo reset_pk_sequences!
che si potrebbe usare:
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
Grazie, Harold. Questo mi sta salvando il culo adesso. –
Roba buona Harold! – RubyFanatic
Il nome della tabella può essere modificato da Rails con 'Class.table_name', che può renderlo ancora più bello. Grazie! –
Presumo che non si preoccupano i dati:
def self.truncate!
connection.execute("truncate table #{quoted_table_name}")
end
o se, ma non troppo (c'è una fetta di tempo in cui i dati esiste solo nella memoria):
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
Questo darà nuovi record, con gli stessi attributi, ma id a partire da 1.
Qualsiasi cosa belongs_to
questo tavolo potrebbe diventare faticoso.
Questa è una risposta chiara, ma il troncamento non è un'opzione per me. Ho imparato qualcosa :) – Trevoke
in base alla risposta @hgmnz s', ho fatto questo metodo che impostare la sequenza a qualsiasi valore che ti piace ... (Solo testato con i Postgres adattatore)
# change the database sequence to force the next record to have a given id
def set_next_id table_name, next_id
connection = ActiveRecord::Base.connection
def connection.set_next_id table, next_id
pk, sequence = pk_and_sequence_for(table)
quoted_sequence = quote_table_name(sequence)
select_value <<-end_sql, 'SCHEMA'
SELECT setval('#{quoted_sequence}', #{next_id}, false)
end_sql
end
connection.set_next_id(table_name, next_id)
end
Funziona fuori dalla scatola ... grazie! – ChaosFreak
Modo rotaie per es. MySQL, ma con persi tutti i dati in tabella users
:
ActiveRecord::Base.connection.execute('TRUNCATE TABLE users;')
aiuta Forse qualcuno;)
Questa è la stessa risposta di https://stackoverflow.com/a/2098639/234025. – Trevoke
- 1. Rails fixtures vs semi
- 2. Impedire Rails prova elimini dati semi
- 3. Rails 4: Differenza tra convalida presenza sul id o associazione
- 4. Ruby on Rails Ordina per ID
- 5. Classi C# per ripristinare i file?
- 6. Mercurial: ripristinare i file
- 7. Per i campi di autoincremento: MAX (ID) vs TOP 1 ID ORDINE PER ID DESC
- 8. Usa ID personalizzato per check_box_tag in Rails
- 9. ID per nulla in Rails 3
- 10. È corretto ripristinare le autorizzazioni per l'app Rails?
- 11. Linq distinta sul campo specifico
- 12. Quanto devono essere diversi i semi casuali?
- 13. Postgres collazione sul campo alias
- 14. Gruppo Magento per clausola sul campo data
- 15. Interfacce generiche per report semi-ad hoc
- 16. Backbone - utilizzando un nome di campo diverso per ID
- 17. Come ripristinare i root node
- 18. Possibili origini per numero casuale semi
- 19. friendly ID e Rails Motori
- 20. Campo temporale database Rails/Activerecord
- 21. javax.persistence Annotazioni sul campo, getter o setter?
- 22. Campo Ruby on Rails medio?
- 23. Quanti giorni aggiungere per "semi-mensile"
- 24. Rails: sul rendimento
- 25. Aggiungere id mettere in campo con ui: dichiarazione di campo
- 26. trucco per ripristinare odbc_error()
- 27. Database di semi per Identity 2
- 28. Enti ServiceStack nome del campo Id
- 29. Rails Formtastic: aggiunta di campo "dati-" per opzione etichetta
- 30. Rails: risolvere l'ambiguità sul gruppo utilizzando simboli
Odio quando la gente dice questo, ma i commenti sono di destra ... non c'è davvero nessun modo per farlo questo in binari, e, in generale, non è necessario farlo affatto. Se stai solo evitando di ottenere numeri grandi perché vuoi visualizzarli per gli utenti, dovresti semplicemente avere una colonna PID e usarla per il tuo display. – aronchick
E come andrei sulla creazione di una colonna PID? È la stessa cosa suggerita da Jonas nella sua risposta? – Trevoke