¿Hay alguna forma de anular el valor de identificación de un modelo en la creación? Algo como:
Post.create(:id => 10, :title => 'Test')
sería ideal, pero obviamente no funcionará.
ruby-on-rails
activerecord
Codebeef
fuente
fuente
Respuestas:
id es solo attr_protected, por lo que no puede usar asignación masiva para configurarlo. Sin embargo, al configurarlo manualmente, simplemente funciona:
No estoy seguro de cuál fue la motivación original, pero hago esto cuando convierto modelos de ActiveHash a ActiveRecord. ActiveHash le permite usar la misma semántica pertenece_ a en ActiveRecord, pero en lugar de tener una migración y crear una tabla, e incurrir en la sobrecarga de la base de datos en cada llamada, simplemente almacena sus datos en archivos yml. Las claves externas en la base de datos hacen referencia a los identificadores en memoria en el archivo yml.
ActiveHash es ideal para listas de selección y tablas pequeñas que cambian con poca frecuencia y solo lo cambian los desarrolladores. Entonces, cuando se pasa de ActiveHash a ActiveRecord, es más fácil mantener todas las referencias de claves externas iguales.
fuente
ActiveRecord::VERSION::STRING == "3.2.11"
aquí (con el adaptador sqlite3) y lo anterior funciona para mí.Tratar
eso debería darte lo que estás buscando.
fuente
También podrías usar algo como esto:
Aunque como se indica en los documentos , esto evitará la seguridad de asignación masiva.
fuente
Para rieles 4:
Otras respuestas de Rails 4 no funcionaron para mí. Muchos de ellos parecían cambiar al verificar usando la consola Rails, pero cuando verifiqué los valores en la base de datos MySQL, permanecieron sin cambios. Otras respuestas solo funcionaron a veces.
Para MySQL al menos, la asignación de un
id
número de identificación por debajo del incremento automático no funciona a menos que useupdate_column
. Por ejemplo,Si cambia
create
para usarnew
+save
, seguirá teniendo este problema. Cambiar manualmente algoid
similarp.id = 10
también produce este problema.En general, usaría
update_column
para cambiar elid
aunque cuesta una consulta de base de datos adicional porque funcionará todo el tiempo. Este es un error que puede no aparecer en su entorno de desarrollo, pero puede corromper silenciosamente su base de datos de producción mientras dice que está funcionando.fuente
Post.new.update(id: 10, title: 'Test')
En realidad, resulta que hacer lo siguiente funciona:
fuente
validate: false
, en lugar de simplementefalse
. Sin embargo, aún se encuentra con el problema del atributo protegido: hay una forma separada de lo que he descrito en mi respuesta.Como señala Jeff, id se comporta como si estuviera attr_protected. Para evitarlo, debe anular la lista de atributos protegidos predeterminados. Tenga cuidado al hacer esto en cualquier lugar donde la información de atributos pueda provenir del exterior. El campo de identificación está protegido por defecto por una razón.
(Probado con ActiveRecord 2.3.5)
fuente
podemos anular atributos_protegido_por_defecto
fuente
Esto no me parece el tipo de cosas que normalmente desearía hacer, pero funciona bastante bien si necesita completar una tabla con un conjunto fijo de identificadores (por ejemplo, al crear valores predeterminados usando una tarea de rake) y usted desea anular el incremento automático (para que cada vez que ejecute la tarea, la tabla se llene con los mismos ID):
fuente
Ponga esta función create_with_id en la parte superior de su seeds.rb y luego úsela para hacer su creación de objetos donde se desean identificadores explícitos.
y úsalo así
En lugar de usar
Foo.create({id:1,name:"My Foo",prop:"My other property"})
fuente
Este caso es un problema similar que fue necesario sobrescribirlo
id
con una especie de fecha personalizada:Y entonces :
Las devoluciones de llamada funcionan bien.
¡Buena suerte!.
fuente
id
marca de tiempo basada en Unix. Lo he hecho por dentrobefore_create
. Funciona bien.Para Rails 3, la forma más sencilla de hacer esto es usar
new
con elwithout_protection
refinamiento y luegosave
:Para los datos de inicialización, puede tener sentido omitir la validación, lo que puede hacer así:
De hecho, hemos agregado un método auxiliar a ActiveRecord :: Base que se declara inmediatamente antes de ejecutar archivos semilla:
Y ahora:
Para Rails 4, debería utilizar StrongParams en lugar de atributos protegidos. Si este es el caso, simplemente podrá asignar y guardar sin pasar ninguna marca a
new
:fuente
{}
la respuesta de Samuel anterior (Rails3).id
sigue siendo 10.id
se pasó como 10, así que eso es exactamente lo que debería ser. Si eso no es lo que esperabas, ¿puedes aclarar con un ejemplo?En Rails 4.2.1 con Postgresql 9.5.3,
Post.create(:id => 10, :title => 'Test')
funciona siempre que no haya una fila con id = 10.fuente
puede insertar id por sql:
fuente