He encontrado las respuestas "puro SQL" a esta pregunta. ¿Hay alguna manera, en Rails, para restablecer el campo id para una tabla específica?
¿Por qué quiero hacer esto? Porque tengo tablas con datos en constante movimiento, raramente más de 100 filas, pero siempre diferentes. Es hasta 25k ahora, y simplemente no tiene sentido. Tengo la intención de utilizar un planificador interno a la aplicación Rails (rufus-scheduler) para ejecutar el reinicio del campo de identificación mensualmente.Rieles forma de restablecer la semilla en el campo id
Respuesta
Salí con una solución basada en la respuesta de hgimenez y this other one.
Como normalmente trabajo con Sqlite o PostgreSQL, solo he desarrollado para aquellos; pero extenderlo a, digamos MySQL, no debería ser demasiado problemático.
poner esto en el interior lib/y requieren en un inicializador:
# 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
Uso:
Client.count # 10
Client.destroy_all
Client.reset_pk_sequence
Client.create(:name => 'Peter') # this client will have id=1
EDIT: Ya que el caso más habitual en el que tendrá que hacer esto es después de limpiar una tabla de base de datos, recomiendo dar un vistazo a database_cleaner. Maneja el restablecimiento de ID automáticamente. Se puede decir que al eliminar tablas acaba de seleccionar como esto:
DatabaseCleaner.clean_with(:truncation, :only => %w[clients employees])
Si eres nuevo en Rails like me, [esta publicación del blog] (http://blog.chrisblunt.com/rails-3-how-to-autoload-and-autorequire-your-custom -library-code /) me ayudó a configurar este código en un inicializador. –
Un problema es que este tipo de campos se implementan de forma diferente para diferentes secuencias databases-, auto-incrementos, etc.
Siempre se puede quitar y volver a agregar la tabla.
No existe tal cosa en Rails. Si necesita una buena identificación para mostrar a los usuarios, guárdela en una tabla separada y vuelva a utilizarla.
¡Eso es inteligente! Sin embargo, no se lo estoy mostrando al usuario. Solo quiero evitar desbordamientos en 10,000 años. :-) – Trevoke
Sólo se podía hacer esto en los carriles si los _ids se están estableciendo por raíles. Siempre que su base de datos establezca los _ids, no podrá controlarlos sin utilizar SQL.
Nota al margen: supongo que utilizar rails para llamar regularmente a un procedimiento de SQL que se restablece o descarta y recrea una secuencia no sería una solución puramente SQL, pero no creo que eso sea lo que estás preguntando ...
EDIT:
de responsabilidad: no sé mucho sobre rieles.
Desde la perspectiva de SQL, si usted tiene una tabla con columnas id first_name last_name
y por lo general insert into table (first_name, last_name) values ('bob', 'smith')
que sólo puede cambiar sus consultas a insert into table (id, first_name, last_name) values ([variable set by rails], 'bob', 'smith')
De esta manera, _ID está fijado por una variable, en lugar de ser ajustados automáticamente por SQL. En ese punto, los rieles tienen control total sobre lo que son los _ids (aunque si es un PK, necesitas asegurarte de no utilizar el mismo valor mientras todavía está allí).
Si va a salir de la asignación hasta la base de datos, usted tiene que tener carriles administrados (en cualquier tiempo del horario) algo como:
DROP SEQUENCE MY_SEQ;
CREATE SEQUENCE MY_SEQ START WITH 1 INCREMENT BY 1 MINVALUE 1;
a cualquier secuencia controla los identificadores para su mesa. Esto eliminará la secuencia actual y creará una nueva. Esta es la forma más sencilla que conozco de 'restablecer' una secuencia.
Bueno, tendré que usar Rails para llamar regularmente a una instrucción SQL para volver a inicializar, creo :) Por curiosidad, ¿cómo haría que Rails establezca el _id? – Trevoke
Nunca mencionó qué DBMS está utilizando. Si esto es PostgreSQL, el postgres adaptador ActiveRecord tiene un método reset_pk_sequences!
que se puede utilizar:
ActiveRecord::Base.connection.reset_pk_sequence!('table_name')
Gracias, Harold. Esto me está salvando el culo ahora mismo. –
¡Buenas cosas, Harold! – RubyFanatic
El nombre de la tabla puede ser inflexionado por Rails con 'Class.table_name', que puede hacerlo aún más agradable. ¡Gracias! –
Asumo que no se preocupan por los datos:
def self.truncate!
connection.execute("truncate table #{quoted_table_name}")
end
O si lo hace, pero no demasiado (hay una porción de tiempo en que los datos sólo existe en la 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
Esto dará a los nuevos registros, con los mismos atributos, sino de identificación a partir de 1.
Cualquier cosa belongs_to
en esta tabla podría resultar molesto.
Esa es una respuesta clara, pero truncar no es una opción para mí. Aunque aprendí algo :) – Trevoke
Basado en @hgmnz 's respuesta, he hecho este método que va a determinar la secuencia en cualquier valor que te gusta ... (Sólo probado con los Postgres adaptador)
# 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
Esto funciona fuera de la caja ... ¡gracias! – ChaosFreak
Rieles, por ejemplo, para MySQL, pero con perdido todos los datos de la tabla users
:
ActiveRecord::Base.connection.execute('TRUNCATE TABLE users;')
Tal vez ayude a alguien;)
Esta es la misma respuesta que https://stackoverflow.com/a/2098639/234025. – Trevoke
- 1. Cómo restablecer la semilla de identidad en SQL Azure
- 2. ¿Restablecer autoincrement ID? phpmyadmin
- 3. rieles Forma simple asociación de encargo de selección de campo
- 4. SQL Server - restablecer el campo de identidad
- 5. importancia de ID de semilla de paquete durante Crear ID de aplicación? (Apple Provisioning Portal)
- 6. ¿Cómo obtener el ID del campo de formulario en Django?
- 7. Rieles: el campo id es nulo cuando se llama a Model.new
- 8. Código EF Primero: cómo establecer la identidad de la semilla?
- 9. Rieles Obtenga Múltiple por ID
- 10. Rails Ruby: recuperar el id del campo de entrada de forma
- 11. rieles formato de fecha en el campo de formulario
- 12. Ajuste y valor en forma sencilla (rieles)
- 13. Etiquetas para botones de radio en forma de rieles
- 14. rieles y forma de diálogo jQuery modal
- 15. Establecer semilla en Math.random()
- 16. ¿cómo validar la presencia de un campo solo si otro campo fue editado en rieles?
- 17. forma de clon y el ID de la subasta
- 18. Rieles: seguimiento del ID de un usuario
- 19. ¿Cómo restablecer una sola tabla en los rieles?
- 20. entidad tipo de campo en forma symfony2.1
- 21. Cambiar ID en forma sencilla
- 22. Despliegue de rieles: la mejor forma
- 23. forma del acceso Selección múltiple de campo en el frasco
- 24. Mejor semilla para el proceso paralelo
- 25. ¿Cómo establecer el valor del campo usando id en javascript?
- 26. El portal de la aplicación para desarrolladores de Apple puede generar un nuevo ID de semilla Bundle
- 27. griales comando unión del campo id
- 28. Rieles ruta a nombre de usuario en lugar de id
- 29. Configuración del aumento de semilla :: aleatorio
- 30. Cambiar la semilla de identidad en SQL Server (¡permanentemente!)
Odio cuando la gente dice esto, pero los comentarios están bien ... realmente no hay manera de hacerlo esto en rieles, y, en general, no es necesario hacerlo en absoluto. Si solo está evitando obtener números grandes porque desea mostrarlos para los usuarios, solo debe tener una columna PID y usarla para su visualización. – aronchick
¿Y cómo podría crear una columna PID? ¿Es eso lo mismo que Jonas sugirió a continuación en su respuesta? – Trevoke