[ruby-on-rails] Anulación de la identificación en create en ActiveRecord



Answers

Tratar

a_post = Post.new do |p| 
  p.id = 10
  p.title = 'Test'
  p.save
end

eso debería darte lo que estás buscando.

Question

¿Hay alguna forma de anular el valor de id de un modelo en create? Algo como:

Post.create(:id => 10, :title => 'Test')

sería ideal, pero obviamente no funcionará.




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.




Como señala Jeff, id se comporta como si estuviera attr_protected. Para evitar eso, debe sobrescribir la lista de atributos protegidos predeterminados. Tenga cuidado al hacer esto en cualquier lugar donde la información de atributos pueda venir del exterior. El campo de id. Está predeterminado protegido por un motivo.

class Post < ActiveRecord::Base

  private

  def attributes_protected_by_default
    []
  end
end

(Probado con ActiveRecord 2.3.5)




Este caso es un problema similar que fue necesario sobrescribir el id con una especie de fecha personalizada:

# in app/models/calendar_block_group.rb
class CalendarBlockGroup < ActiveRecord::Base
...
 before_validation :parse_id

 def parse_id
    self.id = self.date.strftime('%d%m%Y')
 end
...
end

Y entonces :

CalendarBlockGroup.create!(:date => Date.today)
# => #<CalendarBlockGroup id: 27072014, date: "2014-07-27", created_at: "2014-07-27 20:41:49", updated_at: "2014-07-27 20:41:49">

Las rellamadas funcionan bien.

¡Buena suerte!.




Post.create!(:title => "Test") { |t| t.id = 10 }

Esto no me parece el tipo de cosas que normalmente desearía hacer, pero funciona bastante bien si necesita llenar una tabla con un conjunto fijo de identificadores (por ejemplo al crear valores predeterminados usando una tarea de rake) y usted desea anular la autoincrementación (para que cada vez que ejecute la tarea, la tabla se llene con los mismos ID):

post_types.each_with_index do |post_type|
  PostType.create!(:name => post_type) { |t| t.id = i + 1 }
end



Para Rails 4:

Post.create(:title => 'Test').update_column(:id, 10)

Otras respuestas de Rails 4 no funcionaron para mí. Muchos de ellos parecían cambiar al verificar usando Rails Console, pero cuando revisé los valores en la base de datos MySQL, permanecieron sin cambios. Otras respuestas solo funcionaban a veces.

Para MySQL al menos, asignar una id debajo del número de ID de incremento automático no funciona a menos que use update_column . Por ejemplo,

p = Post.create(:title => 'Test')
p.id
=> 20 # 20 was the id the auto increment gave it

p2 = Post.create(:id => 40, :title => 'Test')
p2.id
=> 40 # 40 > the next auto increment id (21) so allow it

p3 = Post.create(:id => 10, :title => 'Test')
p3.id
=> 10 # Go check your database, it may say 41.
# Assigning an id to a number below the next auto generated id will not update the db

Si cambia la create para usar + + save , seguirá teniendo este problema. Cambiar manualmente la id como p.id = 10 también produce este problema.

En general, usaría update_column para cambiar la id aunque cueste 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 todo el tiempo diciendo que está funcionando.




Related