views:

36

answers:

2

I've created a method that allows me to return all of the Books. I'd like to limit the books returned to those that are not not loaned. What do I need to add to *available_books* to ensure only unloaned books are returned. Can I leverage my preexisting loaned? method?

class Book < ActiveRecord::Base
  has_many :book_loans
  has_many :borrowers, :through => :book_loans, :source => :person

  def loaned?
    book_loans.exists?(:return_date => nil)
  end

  def self.available_books
    @books = find(:all, :order => "title")
  end
end
+1  A: 

You can modify your find to make it look like this:

find(:all, :select => "books.*", :joins => :book_loans, :conditions => ['book_loans.return_date is null'], :order => "title")

Vincent
+1  A: 

First off you might want to consider using named scopes in place defining methods, so for example the available_books method you have written could be rewritten as

named_scope :available_books, :order => "title"

Which would allow you to write Book.available_books in the same way you are doing, but in addition you can chain multiple named scopes like Book.available_books.by_author("bob") (assuming you defined another named scope called by_author which took a name as a param.

For checking if it is loaned you could try something like:

named_scope :loaned, :joins => :book_loans, :conditions => { :book_loans => { :return_date => nil } }

Alternatively you should be able to use a string for the conditions in the same way that Vincent has done.

jkupferman