Find_or_initialize_by by has_many association causes a repeated error

I see a strange error since I switched from Rails 3.0.11 to 3.1.3. Here is a separate code for reproducing the error:

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!

finishes ActiveRecord::RecordNotUniquetrying INSERTthe same entry in the table favorites. (Note that in this example, the pair (user_id, site_id) must be unique in favorites)

Interestingly, if I use find_or_createinstead find_or_initialize, there will be no exceptions.

In the stack trace, I noticed that I was autosave_associationreceiving a call, I don’t know why, but in fact it also removes the error has_many :favorites, :autosave => falseinstead has_many :favorites. Since I never cared about autosave, I’m not even sure that :autosave => falseis a good idea or not.

, Rails? - ?

+5
1

f.save!? u.save! , .

> f = u.favorites.find_or_initialize_by_site_id(123)

> u.favorites.include?(f)
==> false

> f2 = u.favorites.build(:site_id => 123)

> u.favorites.include?(f2)
==> true

, , f, , . , f, u.favourites . , u ( )

, , Rails 3.1. .

Rails 3.0 find_or_initialize_by

> f = u.favorites.find_or_initialize_by_site_id(123)

> u.favorites
==> []

- . https://github.com/rails/rails/pull/3610

+5

All Articles