首页 > 解决方案 > Validate uniqueness of rec ord with scope, is not working properly when saving nested records

问题描述

I have a model User with a many-to-many relationship to Book, through UserBook. To create a new relationship, the user can either:

  1. Select from a list of available books
  2. Create a new book request by typing in ISBN code (which can be used to look up the book), they can submit multiple requests at the same time

I'd like to prevent someone from creating duplication in the UserBook model, so I did:

class UserLocation < ApplicationRecord
  belongs_to :user
  belongs_to :book

  validates_uniqueness_of :book_id, scope: :user_id
end

This works fine when a user tries to input a book_id of a book that already exists, but returns with an error. (I can live with this)

The real problem occurs when someone types in the same book_id twice as a new book. This creates two UserLocation records without any error.

I see from the server logs that all the requests to check for uniqueness, are done before the records are saved. Is there a way to do this with model validation?

I'd like to prevent fixing this in the Controller, so not looking for any answers that suggest to deduplicate the array for instance.

标签: ruby-on-rails

解决方案


This is about race conditions.

check concurrency section in this docs

you can avoid to add a unique index like

add_index :user_locations, :book_id, [ :user_id, :book_id ], unique: true

推荐阅读