获取 ActiveRecord::RecordNotUnique 但无法找到现有记录
我有类似下面的代码。 (模型名称已更改,因为它们对发生的事情并不重要。)
#find_or_create_bar_for_blah_id 在大多数情况下都可以正常工作。有时它会返回零,但我不确定为什么。
这是某种竞争条件,因为问题发生在作为我们应用程序一部分运行的 resque 作业中。
关于 #find_or_create_bar_for_blah_id 如何返回 nil 的任何线索?
class Foo < ActiveRecord::Base
has_many :bars, :dependent => :destroy
def find_or_create_bar_for_blah_id(locale_id)
begin
bars.where(:blah_id => blah_id).first || bars.create!(:blah_id => blah_id)
rescue ActiveRecord::RecordNotUnique
bars.where(:blah_id => blah_id).first
end
end
end
class Bar < ActiveRecord::Base
belongs_to :foo
validates_uniqueness_of :blah_id, :scope => :foo_id
end
# db/schema.rb
create_table "bars", :force => true do |t|
t.integer "foo_id"
t.integer "blah_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "bars", ["foo_id", "blah_id"], :name => "index_bars_on_foo_id_and_blah_id", :unique => true
add_index "bars", ["foo_id"], :name => "index_bars_on_foo_id"
create_table "foos", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "foos", ["name"], :name => "index_foos_on_name"
I have something like the following code. (Model names changed as they're not important to what's happening.)
The #find_or_create_bar_for_blah_id works fine most of the time. Occasionally it will return nil though and I'm not sure why.
It's some kind of race condition as the problem happens in resque jobs that run as part of our app.
Any clues as to how #find_or_create_bar_for_blah_id could return nil?
class Foo < ActiveRecord::Base
has_many :bars, :dependent => :destroy
def find_or_create_bar_for_blah_id(locale_id)
begin
bars.where(:blah_id => blah_id).first || bars.create!(:blah_id => blah_id)
rescue ActiveRecord::RecordNotUnique
bars.where(:blah_id => blah_id).first
end
end
end
class Bar < ActiveRecord::Base
belongs_to :foo
validates_uniqueness_of :blah_id, :scope => :foo_id
end
# db/schema.rb
create_table "bars", :force => true do |t|
t.integer "foo_id"
t.integer "blah_id"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "bars", ["foo_id", "blah_id"], :name => "index_bars_on_foo_id_and_blah_id", :unique => true
add_index "bars", ["foo_id"], :name => "index_bars_on_foo_id"
create_table "foos", :force => true do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "foos", ["name"], :name => "index_foos_on_name"
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哎哟!这是因为我们在部分代码中使用了 update_attribute,这当然不会运行 AR 验证。 一脸尴尬
Doh! This was because we were using update_attribute in part of the code, which of course doesn't run AR validations. embarrassed face