has_many 关联上的 find_or_initialize_by 导致重复错误
自从我从 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!
最终会尝试将相同的记录插入到收藏夹表中。 (请注意,在此示例中,(user_id, site_id) 对在收藏夹中必须是唯一的)
有趣的是,如果我使用 find_or_create
而不是 find_or_initialize
,则不会引发异常。
在堆栈跟踪中,我注意到 autosave_association
被调用,不知道为什么,但实际上 has_many :favorites, :autosave => false
而不是 has_many :favorites
也可以消除错误。由于我从来不关心 autosave
,我什至不确定 :autosave => false
是否是一个好主意。
我做错了什么,还是 Rails 的错误?有谁可以指点我看一下吗?
I'm seeing a strange error since I moved from Rails 3.0.11 to 3.1.3. Here's a standalone code to reproduce 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!
will end up ActiveRecord::RecordNotUnique
attempting to INSERT
the same record to the favorites
table. (Note that with this example, (user_id, site_id) pair must be unique on favorites)
Interestingly, if I use find_or_create
instead of find_or_initialize
no exceptions are raised.
In the stack trace I noticed autosave_association
gets called, don't know why, but actually has_many :favorites, :autosave => false
instead of has_many :favorites
removes the error, too. As I've never cared about autosave
, I'm not even sure if :autosave => false
is a good idea or not.
What am I doing wrong, or is it a Rails bug? Can anyone give me a pointer to look at?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您是否尝试过不调用
f.save!
?u.save!
应该保存收藏夹和用户。我认为您会发现您创建的新的最爱
f
是一个单独的对象。因此,您将保存 f,而u.favourites
中还有另一个未保存的收藏夹。因此,当您保存 u (这也保存了收藏夹)时,会发生非唯一错误,我不确定这是否是 Rails 3.1 中新引入的错误。这可能是故意的。
在 Rails 3.0 中 find_or_initialize_by 没有填充数组
看起来像一个错误 - 请参阅 https://github.com/导轨/导轨/拉/3610
have you tried not calling
f.save!
?u.save!
should save both favourites and users.I think what you find is that the new favourite
f
you have created is a separate object. Hence you will be saving f, while there is another un-saved favourite too inu.favourites
. Hence a non-unique error occurs when you save u (which also saves the favourites)I'm not sure if this is a bug newly introduced in Rails 3.1. It may be intentional.
In Rails 3.0 find_or_initialize_by did not populate the array
Looks like a bug - see https://github.com/rails/rails/pull/3610