has_one :through

Another newbie question by me...

I have this:

class User < ActiveRecord::Base
...
        has_one :book, :through => :library
...
end

class Library < ActiveRecord::Base
       has_one :book, :dependent => :destroy
end

class Library < ActiveRecord::Base
  belongs_to :library
  validates_existence_of :library
end

I just don't know what my route will look like. Any help or
suggestions? Are my models correct in how I used the has_one :through

Mike

Thanks

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:

A's has many B's and B's have 1 C.

A = Users
B = Books
C = Libraries

Hope this clarifies everything for you. Sorry about the mistakes in my
first post. Thanks again for your help

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. :slight_smile:

Robert,

Thanks so much for the help. Question, though, could you help with
with the routing that would be involved?