我在 Ruby on Rails 上遇到了一件奇怪的事情,我不知道处理这种情况的正确方法是什么。
我有两个模型,Book 和 Page。
书(名称:字符串)
Page(page_number: integer, book_id: ID)
class Book < ActiveRecord::Base
has_many :pages
accepts_nested_attributes_for :pages
end
class Page < ActiveRecord::Base
belongs_to :book
validates_uniqueness_of :page_number, scope: :book_id
end
我创建了一个可以更新书籍的视图。我接受页面的嵌套属性,并且有一个部分我可以更新书页以及添加新页面(通过一个 Javascript 函数,允许用户通过单击 + 按钮添加新的页面行)。如您所见,我有一个验证,要求某本书的页码是唯一的,以防止重复。我还在数据库级别定义了一个唯一索引(使用 Postgres)
关于我在 Book 控制器中的更新操作,我有:
def update
@book = Book.find(params[:id])
if @book.update_attributes(params[:book])
flash[:notice] = 'Book successfully modified!'
end
end
我的方法的问题是,有时我在 Pages 模型上定义的 page_number 的验证被绕过,我直接从 PG 得到一个错误(“PG::UniqueViolation: ERROR: duplicate key value violates unique constraint”)。
这种情况发生在2个案例上:
似乎存在一些并发问题和处理更新/创建的顺序。
对于第 2 点,我们应该以某种方式告诉 Rails 查看所有记录,看看我们是否试图通过将更新与创建相结合来进行任何重复。第 2 点是一个有效的选项,应该不会抛出验证错误,但是因为 Rails 首先进行创建,它感叹 page_number 4 的页面已经存在(没有考虑 page_number 4 正在更新为 5)
如果你能建议我如何处理这种情况并能够预测所有用例,我将不胜感激,这样我就不会在验证错误的情况下访问数据库。
如果这是不可能的,有没有办法从 Postgres 捕获错误,格式化并将其显示给用户?
感谢任何建议!