2009-01-13 21 views
16

Tengo una pequeña base de datos y he estado agregando entradas a través de una página de Rails. "Destruí" una de las entradas y ahora mi secuencia de ID se salta por uno. Por ejemplo, ahora tengo 42 y 44, en lugar de lo obvio: 42, 43, 44.¿Modificar los ID de la base de datos de la consola de Rails?

Me preguntaba si había una forma de editar el número de ID de un nuevo objeto a través de la consola. He tratado:

record.id = 43 
record.save 

y

record = record.new 
record.attributes = { :id => 43 } 

pero ambos no funcionaba. Estoy bastante seguro de que tiene que haber un método de consola para esto, pero parece que no puedo encontrar mucho específico en Google y probablemente lea incorrectamente la API de Rails ... ¿Tendría que hacerlo posiblemente a través de SQL directo en sqlite? ?

Gracias

Respuesta

4

¿Me posiblemente tenga que hacer esto a través de SQL directa en SQLite?

Sí.

El objetivo de ActiveRecord es que resuma funciones de DB y solo devuelva colecciones de datos. No debería preocuparse por la ID de un registro, que es algo específico de la base de datos. Fuera de mi cabeza, no puedo pensar en ninguna razón para hacer referencia a la identificación del modelo.

Si su aplicación depende de tener un número secuenciado, entonces debe agregar otro campo al modelo que tiene esto. Por ejemplo, si tengo una tienda con productos (un modelo de Producto) y doy el número de ID que el DB proporciona a otros proveedores. Dos semanas después, mi jefe me pide que tenga una identificación única pero similar para dos variaciones de productos: "45a" y "45b". Nueces. El campo ID solo se debe utilizar en la base de datos y ActiveRecord, no usted ni sus usuarios, para identificar el registro.

Existe una pequeña posibilidad de que podría ser un método oscuro que forza el ID si el DB lo permite, pero es oscuro por alguna razón. No intente encontrarlo :)

Dicho todo esto, escriba ruby script/dbconsole para abrir rápidamente la interfaz sqlite sin tener que escribir su contraseña.

Además, si elimina la base de datos sqlite que restablecerá el contador y comenzará en 0. Con gran potencia viene una gran responsabilidad.

EDITAR

Si no recuerdo mal Dave Thomas escribió sobre esto en alguna parte. Tal vez here?

+1

Este fue un comentario realmente sarcástico e inútil. No vale la pena marcar, pero vale la pena revisarlo. – ivanreese

23

En realidad, se puede configurar el identificador del manual para los nuevos objetos:

record = Record.new 
record.id = 1234 
record.save 

Sin embargo, lo que estamos tratando de hacer es actualizar el identificador de un objeto existente.Cuando se establece record.id = 43 y luego llamar save lo que sucede es que ActiveRecord intentará generar SQL como esto:

update records set id = 43 where id = 43

en cuenta que el id que está buscando para actualizar es el mismo que el que usted está tratando para cambiar. Es por eso que no funciona.

Así que sí, tendría que usar SQL para cambiar esto. Si esa es una buena idea o no es otro problema, pero a veces es necesario hacerlo.

+0

El primer código funcionó para mí. ¡Gracias! –

+1

Gran solución, desearía poder votar doblemente para llegar a la cima. Amo las soluciones que explican el problema. Y he encontrado uso para esto para implementar "enumeraciones" normalizadas. Por ejemplo, un usuario puede tener muchos roles, pero esos roles van a ser consistentes en todas las implementaciones, por lo que los agrego con una tarea de rake. La codificación dura de sus identificaciones garantiza que sean iguales en mi caja local y en el servidor. Nitpicky, y posiblemente nunca sea necesario, pero me hace un poco menos inquieto :) –

39

La mejor manera de hacerlo es ejecutar el SQL directamente, y resolver este problema temporal en la secuencia.

Intenta acceder a la consola (rubí script/consola) y el tipo:

>> sql = "update records set id=43 where id=44" 
>> ActiveRecord::Base.connection.execute(sql) 

Donde 44 es el ID del nuevo objeto creado, y el 43 es el que no aparecen en la tabla

Buena suerte !

+0

Me funcionó. ¡Gracias! –

+1

Acepto que cambiar una identificación es una mala idea, pero cuando necesita restaurar los datos en, por ejemplo, una base de datos de producción cuando 'perdió' algunos registros? Esto es perfecto. –

+2

también es bueno si tiene dos sistemas que tienen que sincronizarse .. – baash05

Cuestiones relacionadas