Veo un error extraño desde que cambié de Rails 3.0.11 a 3.1.3. Aquí hay un código independiente para reproducir el error:find_or_initialize_by en la asociación has_many provoca un error duplicado
require 'active_record'
ActiveRecord::Base.establish_connection(
:adapter => 'mysql2',
:username => 'root',
:database => "some_development"
)
class User < ActiveRecord::Base
has_many :favorites
end
class Favorite < ActiveRecord::Base
belongs_to :user
end
u = User.create
# f = u.favorites.find_or_create_by_site_id(123) #=> pass
f = u.favorites.find_or_initialize_by_site_id(123) #=> fail
f.some_attr = 'foo'
f.save!
u.name = 'bar'
u.save! # ActiveRecord::RecordNotUnique will be thrown here!
terminará ActiveRecord::RecordNotUnique
intentar INSERT
el mismo registro a la tabla favorites
. (Tenga en cuenta que con este ejemplo, (user_id, site_id) par debe ser único en favoritos)
Curiosamente, si uso find_or_create
en lugar de find_or_initialize
no hay excepciones son criados.
En el seguimiento de la pila noté que se llama autosave_association
, no sé por qué, pero en realidad has_many :favorites, :autosave => false
en lugar de has_many :favorites
también elimina el error. Como nunca me ha importado autosave
, ni siquiera estoy seguro de si :autosave => false
es una buena idea o no.
¿Qué estoy haciendo mal, o es un error de Rails? ¿Alguien puede darme un puntero para mirar?
¿El modelo de usuario tienen una validación para la unicidad de un campo? Además, ¿qué es esa línea comentada con '# => pass' junto a ella? ¿Estás tratando de crear dos versiones de favoritos a la vez o algo así? – Batkins
Sí, el modelo de usuario tiene un montón de validaciones, incluida la exclusividad, aunque no estoy seguro de cómo se relaciona. Si hace un comentario, en la línea de find_or_create en lugar de find_or_initialize, debería pasar sin error, como se describe en mi pregunta. – kenn
Puedes probar esto: en lugar de 'u.save!', Haz 'u.save' y luego' puts u.errors' or 'p u.errors'. ¿Cuáles son los errores? Tengo la sensación de que este es un problema en el que está creando un usuario que no pasa una de las validaciones por exclusividad (ya que está utilizando un 'User.create' genérico sin atributos que se ingresen). – Batkins