[LRUG] Enforcing uniqueness
Andrew Stewart
boss at airbladesoftware.com
Mon Nov 14 04:00:16 PST 2011
On 11 Nov 2011, at 15:22, Andrew Stewart wrote:
> I cannot figure out how to ensure a book can't end up with two current loans in the database.
Thanks, everyone, for all the suggestions.
I like the idea of a unique partial index but unfortunately I'm still using an inferior database (MySQL)!
I think a before save callback alone isn't quite enough. Despite being transactional, I don't think the default isolation level of MySQL will prevent duplicate loans. And I don't want to tinker with the database's isolation level.
I'm not keen on juggling extra models or tables: too much to go wrong.
Adding a flag to the loan model to permit a unique index is mildly hacky but straightforward.
In fact that last idea reminded me that I need to give book a state (as in state machine): as well as being available or on loan, a book can also be lost or donated.
Now if book has a state column, I think I can use Rails' pessimistic locking[1] (select ... for update) to manage the state change like this:
Book.transaction do
book = Book.find(params[:id]).lock!
if book.state == :available
book.loans.create params[:loan]
book.state = :on_loan
end
end
[1] http://railsapi.com/doc/rails-v3.0.8rc1/classes/ActiveRecord/Locking/Pessimistic.html
Does that sound sensible?
Thanks again,
Andy
-------
http://airbladesoftware.com
More information about the Chat
mailing list