2015-10-16 101 views
6

我正在使用Rails 4.2。我有3個表是這樣的:Rails:`包括``has_many`與`limit`的關係

class Collection < ActiveRecord::Base 
    has_many :shares 
    has_many :images, through: :shares 
    has_many :latest_images, -> { order(created_at: :desc).limit(10) }, class_name: 'Image', through: :shares, source: :image 
end 

class Share < ActiveRecord::Base 
    belongs_to :image 
    belongs_to :collection 
end 

class Image < ActiveRecord::Base 
    has_many :shares 
    has_many :collections, through: :shares 
end 

我的目標是選擇一些收藏和使用latest_images關係預裝每個集合的第10張最新的卡。

如果我做的只是:

collections = Collection.where(some_condition).includes(:latest_images) 

的問題是latest_images將包含所有的卡,不僅在過去10(即使有一個limit(10)

collections.first.latest_images.count # => more than 10!!! 

相反,如果我添加limit(10)加載收藏後,我會遇到N + 1個查詢問題:

collections.each { |collection| collection.latest_images.limit(10).do_something } # N+1 QUERY 

任何解決方案?

回答

3

有記下associations documentation藏下的「協會的預先加載」:

如果你渴望負載與指定的關聯:限制選項,它會被忽略,返回所有相關聯的對象。

因此,即使這可能不是直觀的行爲,它的行爲仍像記錄一樣。

解決的辦法是到不是急切加載有限關聯,然後單獨訪問。正如你指出這並不理想,但幾乎可以肯定的是加載所有關聯的對象沒有限制。

+0

那麼沒有辦法在不加載任何東西的情況下加載那些數據並避免N + 1查詢? – ProGM

+2

不,不使用arel接口我不這麼認爲。你可以編寫你自己的代碼來做到這一點我猜,但你不會很遺憾地得到它。 – Shadwell