【问题标题】:Rails 5 Postgres Duplicate Key Violation on createRails 5 Postgres在创建时重复密钥冲突
【发布时间】:2016-09-23 17:51:35
【问题描述】:

在 Rails 5 应用程序中,我创建项目并增加它们的位置:

class ListItem < ActiveRecord::Base
  belongs_to :list

  before_validation :ensure_position

  private
  def ensure_position
    self.position ||= self.class.where(list_id: list_id).maximum(:position).to_i + 1
  end
end

导致重复违规的索引是:

 t.index ["list_id", "position"]

我在 :position 列上发现 PG 重复键违规。每当同时触发多个 create 时,maximum 函数都会为多个记录返回相同的位置。

我是线程安全和 postgres 锁定在 ruby​​ on rails 的新手。有没有办法在列表项记录的保存操作上锁定或创建互斥锁,以便安全地增加位置?

【问题讨论】:

  • 为什么不像往常一样使用数据库中的序列?
  • 对不起,我是新手,序列不是唯一的增量列吗?在我的场景中 :position 不是唯一的,唯一的是 [:list_id, :position]。

标签: ruby-on-rails postgresql model constraints


【解决方案1】:

你想要一个 Rails 不支持的复合主键。

但是,有一个 composite_primary_keys gem 和一个 blog post 关于使用 gem。

【讨论】:

  • 感谢您的建议。我目前正在检查 gem 并且博客文章很有趣,但是您不认为整个 gem 对于这么小的部分来说有点矫枉过正吗?如果您考虑解决方法,这将非常有帮助。
  • 好吧,Sami 已经建议了一个类似stackoverflow.com/a/36720571/4812102 的序列“没有什么能阻止你将你认为的复合主键作为替代键并使用 Rails 默认 PK (postgres: pseudotype' serial' 从序列中提取其值)。只需确保为构成键的那些列添加唯一索引即可。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 2015-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-27
  • 2013-01-03
相关资源
最近更新 更多