2013-04-22 87 views
0

這是我的模型:活動記錄:聯接查詢與「where」子句

class Book < ActiveRecord::Base 
    attr_accessible :author, :title 
    validates :author, presence: true 
    validates :title, :uniqueness => true, presence: true 

    has_many :rentals 

    def rent? 
     rentals.where(return_date: nil).count > 0 
    end 
end 

class Rental < ActiveRecord::Base 
    belongs_to :student 
    belongs_to :book 

    validates :student, presence: true 
    validates :book, presence: true 
    validates :rental_date, presence: true 

    attr_accessible :rental_date, :return_date, :student, :book 

    def pending? 
     return return_date == nil 
    end 

    def overdue? 
     if(return_date) 
      return_date - rental_date > 7.days 
     else 
      Time.now - rental_date > 7.days 
     end 
    end 
end 

我想查詢所有不在租金書(即有這本書,沒有任何租金有一個return_date)。

我以爲我可以用我的「租金?」方法,但我無法使它工作,所以我試圖加入。

這是我得到:

Book.includes(:rentals).find(:all, :conditions => ['"rentals"."return_date" is NULL']) 

但我也想添加基於我的PARAMS一些地方查詢。

我該如何做到這一點?

回答

0

你應該使用joins

Book.joins('LEFT OUTER JOIN rentals ON books.id = rentals.book_id') 
    .where('rentals.return_date IS NULL') 
+0

但是,使用這種方法,會做一個內部聯接,我需要一個外部聯接。所以我可以列出每本沒有return_date的書和沒有租過的書。 – 2013-04-23 01:31:03

+0

@DavidAnderson看到我的編輯,你可以使用'join'的外連接。 – xdazz 2013-04-23 02:33:31

1

joins方法將左外連接的工作,但你需要自己構建SQL片段。下面演示了這一點,並結合merge和租賃範圍中的附加範圍。

class Rental < ActiveRecord::Base 
    scope :no_return, where('return_date IS NULL') 
end 

join_statement = 'LEFT OUTER JOIN rentals ON rentals.book_id = books.id' 
Book.joins(join_statement).merge(Rental.no_return) 
# => returns set of books with no rentals and 
# books with rentals that have no return date 

在一個不相關的音符,你會發現,許多喜歡寫你的pending?方法,像這樣:

def pending? 
    return_date.nil? 
end