mlittle wrote:
Robert, thanks for the reply. validates_existence_of is a plugin ->
http://github.com/bogdans83/validates_existence_of/. I'll try to make
this as simple as possible. Here is what i'm trying to do:
Got it. I though maybe that was the case, and might explain some of my
previous frustrations with testing these associations.
A's has many B's and B's have 1 C.
A = Users
B = Books
C = Libraries
Okay, That makes more sense. Let me first write this as a user story:
Users may check out many books from a library. Users may borrow from
many libraries. Only one library may own a book (in this design let's
consider two books with the same title separate books). Books loaned to
users must be returned to the owning library.
So I see four models here not three:
User
Library
Book
Loan
Feature: Book check out
In order to learn cool stuff, or be entertained
As a user
I want to be able to checkout many books from many libraries
Scenario: Check from 2 libraries
Given I select 'Programming Ruby' from the Public Library
And I select 'The Rails Way' from the University Library
When I check out from the Public Library
And I check out from the University Library
Then I should have 2 books
Feature: Book check in
In order to prevent late fees
As a user
I want to be able to check in books
Scenario: I must return a book to the correct library
Given I have 'Programming Ruby'
When I check in to the University Library
Then the check in should be denied
And I should have 2 books
There may be other scenarios to consider, but I wanted to focus on these
two to help describe the model:
It looks to me like you need a standard many-to-many association with
some additional validation to make sure the books get returned back to
the library that owns them.
class User < ActiveRecord::Base
has_many :loans
has_many :books, :through => :loans
end
class Loan < ActiveRecord::Base
belongs_to :user
belongs_to :book
end
class Book < ActiveRecord::Base
has_many :loans
has_many :users, :through => :loans
belongs_to :library
end
class Library < ActiveRecord::Base
has_many :books
end
loans_controller.rb
# DELETE /loans/1
# DELETE /loans/1.xml
def destroy
@loan = Loan.find(params[:id])
@loan.destroy if @loan.book.library == current_library
respond_to do |format|
flash[:error] = "This book was
format.html { redirect_to(loans_url) }
format.xml { head :ok }
end
end
I'll leave it as an exercise for you to figure out how to determine the
"current library" that the user is attempting to return the book to.
Notice that in this design the act of checking in a book is to destroy
the loan of the book. So loan is a resource in it's own right. Of course
checking out a book would be to create a new loan.
Note: this code is incomplete and untested with no warrantee of any
kind. 