我使用的是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选项加载关联,它将被忽略,返回所有关联的对象。
所以,它的行为与文档一样,即使这可能不是直观的行为。
的解决方法是而不是立即加载相关的有限内容,然后单独访问。正如您所指出的,这并不理想,但几乎可以肯定,它比加载所有相关对象没有限制更可取。