Rails: '包含'与' limit '的' has_many '关系



我使用的是Rails 4.2。我有3个这样的表:

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

解决方案吗?

在关联文档中"主动加载关联"下面隐藏着一条注释:

如果你用指定的:limit选项加载关联,它将被忽略,返回所有关联的对象。

所以,它的行为与文档一样,即使这可能不是直观的行为。

的解决方法是而不是立即加载相关的有限内容,然后单独访问。正如您所指出的,这并不理想,但几乎可以肯定,它比加载所有相关对象没有限制更可取。

最新更新