J'ai trouvé les réponses "pur SQL" à cette question. Y at-il un moyen, dans Rails, pour réinitialiser le champ id pour une table spécifique?
Pourquoi est-ce que je veux faire ceci? Parce que j'ai des tables avec des données en mouvement constant - rarement plus de 100 lignes, mais toujours différentes. C'est jusqu'à 25k maintenant, et il n'y a juste aucun point dans cela. J'ai l'intention d'utiliser un planificateur interne à l'application Rails (rufus-scheduler) pour exécuter la réinitialisation du champ d'identification tous les mois.Rails façon de réinitialiser la graine sur le champ id
Répondre
Je suis sorti avec une solution basée sur la réponse de hgimenez et this other one.
Depuis que je travaille habituellement avec Sqlite ou PostgreSQL, je n'ai développé que pour ceux-ci; mais l'étendre à, disons MySQL, ne devrait pas être trop gênant.
Mettre cela à l'intérieur lib/et nécessitent sur un initialiseur:
# 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
Utilisation:
Client.count # 10
Client.destroy_all
Client.reset_pk_sequence
Client.create(:name => 'Peter') # this client will have id=1
EDIT: Comme le cas le plus courant dans lequel vous voulez faire est après avoir terminé une table de base de données, je recommande de donner un coup d'oeil à database_cleaner. Il gère la réinitialisation de l'ID automatiquement. Vous pouvez lui dire de supprimer des tables sélectionnées simplement comme ceci:
DatabaseCleaner.clean_with(:truncation, :only => %w[clients employees])
Si vous êtes nouveau sur Rails comme moi, [ce blog] (http://blog.chrisblunt.com/rails-3-how-to-autoload-and-autorequire-your-custom -library-code /) m'a aidé à configurer ce code dans un initialiseur. –
Un problème est que ces types de champs sont mis en œuvre différemment pour différentes séquences databases-, incrémente automatiquement, etc.
Vous pouvez toujours déposer et rajoutez la table.
Il n'y a rien de tel dans Rails. Si vous avez besoin d'un ID sympa pour montrer les utilisateurs, stockez-les dans une table séparée et réutilisez-les.
C'est intelligent! Je ne le montre pas à l'utilisateur cependant. Je veux juste éviter de déborder en 10 000 ans. :-) – Trevoke
Vous pouvez uniquement faire cela dans les rails si les _ids sont définis par des rails. Tant que les _ids sont définis par votre base de données, vous ne pourrez pas les contrôler sans utiliser SQL. Note: Je suppose que l'utilisation de rails pour appeler régulièrement une procédure SQL qui réinitialise ou supprime et recrée une séquence ne serait pas une solution purement SQL, mais je ne pense pas que ce soit ce que vous demandez ...
EDIT:
Disclaimer: Je ne sais pas beaucoup sur les rails.
Du point de vue SQL, si vous avez une table avec des colonnes id first_name last_name
et vous habituellement insert into table (first_name, last_name) values ('bob', 'smith')
vous pouvez simplement changer vos questions à insert into table (id, first_name, last_name) values ([variable set by rails], 'bob', 'smith')
De cette façon, le _id est fixé par une variable, au lieu d'être réglée automatiquement par SQL. À ce stade, les rails ont tout le contrôle sur ce que sont les _ids (bien que si c'est un PK, vous devez vous assurer que vous n'utilisez pas la même valeur alors qu'il est encore là).
Si vous allez quitter l'affectation à la base de données, vous devez avoir rails cheminent (quel qu'en soit le temps horaire) quelque chose comme:
DROP SEQUENCE MY_SEQ;
CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1;
à quelque séquence contrôle les ids pour votre table. Cela va se débarrasser de la séquence actuelle, et en créer une nouvelle. C'est la manière la plus simple que je connaisse de vous 'réinitialiser' une séquence.
Eh bien, je vais devoir utiliser Rails pour appeler régulièrement une instruction SQL pour re-semer, je pense :) Par curiosité, comment pourrais-je faire Rails définir le _id? – Trevoke
Vous n'avez jamais mentionné le SGBD que vous utilisez. Si cela est postgreSQL, l'adaptateur postgres ActiveRecord a une méthode reset_pk_sequences!
que vous pouvez utiliser:
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
Merci, Harold. C'est sauver mon cul en ce moment. –
Bonnes affaires Harold! – RubyFanatic
Le nom de la table peut être fléchi par Rails avec 'Class.table_name', ce qui peut le rendre encore plus agréable. Merci! –
Je suppose que vous ne vous souciez pas les données:
def self.truncate!
connection.execute("truncate table #{quoted_table_name}")
end
Ou si vous le faites, mais pas trop (il y a une tranche de temps où les données existent uniquement en mémoire):
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
Cela donnera de nouveaux records, avec les mêmes attributs, mais id à partir de 1.
Quelque chose belongs_to
cette table pourrait se visse.
C'est une réponse soignée, mais tronquer n'est pas une option pour moi. J'ai appris quelque chose si :) – Trevoke
Sur la base de la réponse de @hgmnz, je fait cette méthode qui définira la séquence à une valeur quelconque ... (testé uniquement avec les Postgres adaptateur.)
# 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
Cela fonctionne hors de la boîte ... merci! – ChaosFreak
Rails chemin pour par exemple MySQL, mais avec toutes les données perdues dans le tableau users
:
ActiveRecord::Base.connection.execute('TRUNCATE TABLE users;')
aide Peut-être quelqu'un;)
Voici la même réponse que https://stackoverflow.com/a/2098639/234025. – Trevoke
- 1. Rails passent ID de auto_complete champ observe_field
- 2. comment réinitialiser le champ de saisie après la validation échoue?
- 3. .save met NULL dans le champ id dans Rails
- 4. Mauvais fonctionnement db: graine dans Rails
- 5. SQL Server - réinitialiser le champ d'identité
- 6. Comment réinitialiser le champ de saisie dans l'iframe?
- 7. Comment réinitialiser le numéro de notificationmanager sur la notification d'effacement
- 8. Comment définir la graine MessageDigest?
- 9. Comment réinitialiser le clavier d'un champ de saisie?
- 10. Ruby On Rails ID personnalisé
- 11. GQL obtenir champ ID
- 12. php mysql si id dans le champ
- 13. Réinitialiser setinterval sur cliquez
- 14. Odd nhibernate question sur la modification d'un PK à juste un champ Id dans le mappage
- 15. Connexion Réinitialiser sur requête MySQL
- 16. puis-je réinitialiser le champ auto_increment dans mySql?
- 17. réinitialiser l'application sur la sortie de l'utilisateur
- 18. Ruby on Rails: Comment graine-t-on la colonne * _type dans les modèles polymorphes?
- 19. La meilleure façon de stocker seulement la date sur le champ datetime?
- 20. Connexion ASP.NET Réinitialiser sur le téléchargement
- 21. Rails 2.3.5: Comment ajouter un champ: id à un espace de noms?
- 22. jQuery: find id d'un champ de formulaire
- 23. Réinitialiser la force sur une requête ajax?
- 24. Réinitialiser le numéro d'identification automatique (champ d'identité) dans la base de données
- 25. Meilleure façon de créer un champ ID unique pour une énumération
- 26. Meilleure façon de stocker le champ de type muti
- 27. Qu'est-ce que le Rails 3 façon de faire une validation de champ de formulaire avant la soumission?
- 28. Rails table relationnelle avec plusieurs ID de la même table
- 29. Définir l'identité de la graine à 0 à l'aide de NHibernate SchemaExport
- 30. Ruby on Rails formulaire_pour sélectionner le champ avec la classe
Je déteste quand les gens disent cela, mais les commentaires sont bien ... il n'y a vraiment aucun moyen de faire ceci dans les rails, et, dans l'ensemble, ce n'est pas nécessaire du tout. Si vous évitez simplement d'obtenir de grands nombres parce que vous voulez l'afficher pour les utilisateurs, vous devriez juste avoir une colonne PID, et l'utiliser pour votre affichage. – aronchick
Et comment pourrais-je créer une colonne PID? Est-ce la même chose que Jonas suggérée ci-dessous dans sa réponse? – Trevoke