Suppose I have two classes
class student < ApplicationRecord
has_many :books
end
class Book < ApplicationRecord
belongs_to :student
end
Each book will have a boolean variable read indicating if the book has been read or not. Each student can only read one book. If any of a student's book is marked as read, his other books cannot be read anymore.
Is there a PSQL or active-record validation to allow this constraint to happen?
Specifically, book.update_attributes!(read: true) will do a check on other associated books. DB constraints would be much preferred.
Much thanks!
Update to problem statement:
read becomes a timestamp read_at and book.update_attributes!(read_at: Time.zone.now) will do a check if the student has read any other books previously.
Add an unique partial index on a boolean read field and integer student_id field where read is equal true
add_column :books, :read, :boolean, null: false, default: false
add_index :books, [:student_id, :read], unique: true, where: "read=true"
In Book model add unique validation that will works only when book.read == true
validates :read, uniqueness: { scope: :student_id }, if: -> (book) { book.read }