5

自从我从 Rails 3.0.11 迁移到 3.1.3 后,我看到了一个奇怪的错误。这是重现错误的独立代码:

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!

最终将ActiveRecord::RecordNotUnique尝试INSERT将相同的记录添加到favorites表中。(请注意,在此示例中, (user_id, site_id) 对在收藏夹中必须是唯一的)

有趣的是,如果我使用find_or_create而不是find_or_initialize引发异常。

在我注意到的堆栈跟踪中autosave_association被调用,不知道为什么,但实际上也has_many :favorites, :autosave => false没有has_many :favorites删除错误。由于我从不关心autosave,我什至不确定这是否:autosave => false是个好主意。

我做错了什么,还是 Rails 错误?谁能给我指点看看?

4

1 回答 1

5

你试过不打电话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

于 2012-01-10T04:46:58.973 回答