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?