คุณสามารถใช้validates
เพื่อตรวจสอบความถูกต้องuniqueness
ในหนึ่งคอลัมน์:
validates :user_id, uniqueness: {scope: :friend_id}
ไวยากรณ์สำหรับการตรวจสอบความถูกต้องในหลายคอลัมน์มีความคล้ายคลึงกัน แต่คุณควรระบุอาร์เรย์ของฟิลด์แทน:
validates :attr, uniqueness: {scope: [:attr1, ... , :attrn]}
อย่างไรก็ตามวิธีการตรวจสอบที่แสดงข้างต้นมีเงื่อนไขการแข่งขันและไม่สามารถมั่นใจได้ว่ามีความสอดคล้อง ลองพิจารณาตัวอย่างต่อไปนี้:
บันทึกตารางฐานข้อมูลควรจะไม่ซ้ำกันโดยเขตข้อมูลn ;
คำขอพร้อมกันจำนวนมาก ( สองขึ้นไป ) จัดการโดยกระบวนการที่แยกจากกัน ( เซิร์ฟเวอร์แอปพลิเคชันเซิร์ฟเวอร์ผู้ทำงานเบื้องหลังหรือสิ่งที่คุณกำลังใช้ ) ฐานข้อมูลการเข้าถึงเพื่อแทรกระเบียนเดียวกันในตาราง
แต่ละกระบวนการในแบบคู่ขนานจะตรวจสอบว่ามีเร็กคอร์ดที่มีฟิลด์nเดียวกันหรือไม่
การตรวจสอบความถูกต้องสำหรับแต่ละคำร้องขอถูกส่งสำเร็จและแต่ละกระบวนการสร้างเรกคอร์ดในตารางด้วยข้อมูลเดียวกัน
เพื่อหลีกเลี่ยงพฤติกรรมเช่นนี้ควรเพิ่มข้อ จำกัด ที่ไม่ซ้ำกันลงในตาราง db คุณสามารถตั้งค่าด้วยตัวadd_index
ช่วยสำหรับหนึ่ง (หรือหลายรายการ) โดยเรียกใช้การโยกย้ายต่อไปนี้:
class AddUniqueConstraints < ActiveRecord::Migration
def change
add_index :table_name, [:field1, ... , :fieldn], unique: true
end
end
ข้อแม้ : แม้หลังจากที่คุณได้ตั้งข้อ จำกัด ที่ไม่ซ้ำกันแล้วคำขอสองคำขอพร้อมกันจะพยายามเขียนข้อมูลเดียวกันไปยัง db แต่แทนที่จะสร้างระเบียนที่ซ้ำกันสิ่งนี้จะทำให้เกิดActiveRecord::RecordNotUnique
ข้อยกเว้นซึ่งคุณควรจัดการแยกต่างหาก:
begin
# writing to database
rescue ActiveRecord::RecordNotUnique => e
# handling the case when record already exists
end