Rails 5:查找或创建 .each do



我正在向Typeform发出GET请求。如果请求成功,我将响应保存为数据库order。我的问题在于这个特定部分:

current_user.find_or_create_by(landing_id: item["landing_id]) do |order|

如果用户提交新的 Typeform,该方法将找不到landing_id,因此将再次创建所有orders。但是这些orders已经存在于数据库中,因此每个order都多次保存到我的数据库中。

我怎样才能避免这种情况?

items = response.parsed_response["items"]
 items.each do |item|
  @order = current_user.orders.find_or_create_by(landing_id: item["landing_id"]) do |order|
   order.landing_id = item["landing_id"]
   order.email = item["hidden"]["email"]
   order.price = item["hidden"]["price"]
   order.project = item["hidden"]["project"]
   order.save!
  end
 end

find_or_create_by的活动记录文档:

请注意,此方法不是原子的,它首先运行 SELECT,如果没有结果,则尝试插入。如果还有其他线程或进程,则两个调用之间存在争用条件,并且可能最终会得到两个相似的记录。

无论如何,您可以通过向user_idlanding_id列的组合添加 uniq 约束来解决此问题:

add_index :orders, [:user_id, :landing_id], unique: true

并相应地更改您的代码:

items = response.parsed_response["items"]
items.each do |item|
  begin
    Order.transaction(requires_new: true) do
      @order = current_user.orders.find_or_create_by(landing_id: item["landing_id"]) do |order|
        order.landing_id = item["landing_id"]
        order.email = item["hidden"]["email"]
        order.price = item["hidden"]["price"]
        order.project = item["hidden"]["project"]
        order.save!
      end
    end
  rescue ActiveRecord::RecordNotUnique
    next
  end
end

最新更新