获取 ActiveRecord::RecordNotUnique 但无法找到现有记录

发布于 2024-12-22 02:10:22 字数 1223 浏览 5 评论 0原文

我有类似下面的代码。 (模型名称已更改,因为它们对发生的事情并不重要。)

#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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜唯美灬不弃 2024-12-29 02:10:22

哎哟!这是因为我们在部分代码中使用了 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文