Rails一对多:验证字段值

时间:2017-04-18 22:10:00

标签: ruby-on-rails postgresql validation activerecord psql

假设我有两个班级

    class student < ApplicationRecord
      has_many :books
    end

    class Book < ApplicationRecord
      belongs_to :student
    end

每本书都有一个布尔变量read,表明该书是否已被阅读。每个学生只能读一本书。如果学生的任何一本书被标记为已阅读,则他的其他书籍将不再被阅读。

是否存在PSQL或活动记录验证以允许此约束发生?

具体来说,book.update_attributes!(read: true)会检查其他相关图书。数据库约束会更受欢迎。

非常感谢!

更新问题陈述:

读取成为时间戳read_at,book.update_attributes!(read_at: Time.zone.now)将检查学生之前是否读过任何其他书籍。

1 个答案:

答案 0 :(得分:1)

在布尔read字段和整数student_id字段上添加唯一的部分索引,其中read等于true

add_column :books, :read, :boolean, null: false, default: false
add_index :books, [:student_id, :read], unique: true, where: "read=true"

在Book模型中添加仅在book.read == true

时才有效的唯一验证
validates :read, uniqueness: { scope: :student_id }, if: -> (book) { book.read }