2013-04-22 91 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