ruby-on-rails - rails : `includes` a `has_many` relation with `limit`

标签 ruby-on-rails ruby-on-rails-4 activerecord

我正在使用 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

有什么解决办法吗?

最佳答案

associations documentation 中藏有一张纸条在“渴望加载关联”下:

If you eager load an association with a specified :limit option, it will be ignored, returning all the associated objects.



因此,即使这可能不是直观的行为,它的行为也与文档一致。

解决方法是不要急切加载有限的关联并在之后单独访问。正如您指出的那样,这并不理想,但几乎肯定比无限制地加载所有关联对象更可取。

关于ruby-on-rails - rails : `includes` a `has_many` relation with `limit` ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33174701/

相关文章:

ruby-on-rails - Rails 4 Devise/Omniauth 电子邮件存在于数据库错误

ruby-on-rails - 从任何路径将正斜杠替换为 ruby​​ 中的反斜杠

ruby - 导轨 3 : method delegations with nil relationships

ruby-on-rails - Rails,如何为模型中的关系别名?

ruby-on-rails - Rails协会has_one最新记录

ruby-on-rails - ‘要求’: can not load such file -- sqlite3/sqlite3_native (LoadError)

ruby-on-rails - Webrick 死于非法指导 4

ruby-on-rails - 使用 database_cleaner、mongoid 和 active_admin 会导致规范因 ActiveRecord::ConnectionNotEstablished 而失败

ruby - `threadsafe!` rails 中缺少方法

ruby-on-rails - Rails 4 i18n,如何在将子域用作语言环境的地方转换路线