Rails 7 中添加了对实例相关关联预加载的支持。 https://github.com/rails/rails/pull/42553
但是,当我将应用程序升级到 Rails 7.0.3 时,对需要预加载的此类关联运行查询仍然不起作用。
我的模特:
class Artist < ApplicationRecord
has_many :artist_masters, ->(artist) {
unscope(:where).where(artist_id: artist.id)
.or(where(composer_id: artist.id))
.or(where(performer_id: artist.id))
.or(where(conductor_id: artist.id))
}, dependent: :destroy
has_many :masters, through: :artist_masters
end
class ArtistMaster < ApplicationRecord
belongs_to :master
belongs_to :artist, optional: true
belongs_to :composer, class_name: 'Artist', optional: true
belongs_to :performer, class_name: 'Artist', optional: true
belongs_to :conductor, class_name: 'Artist', optional: true
end
class Master < ApplicationRecord
has_many :artist_masters, dependent: :destroy
has_many :artists, through: :artist_masters
has_many :composers, class_name: 'Artist', through: :artist_masters
has_many :performers, class_name: 'Artist', through: :artist_masters
has_many :conductors, class_name: 'Artist', through: :artist_masters
end
当我运行
Artist.where.missing(:artist_masters).first
时,我收到错误:
ArgumentError:关联范围“artist_masters”依赖于实例(范围块带有一个参数)。不支持预先加载实例相关范围。
来自 /usr/local/bundle/gems/activerecord-7.0.3/lib/active_record/reflection.rb:500:in `check_eager_loadable!'
有人能解释一下为什么这不起作用吗?
这里的错误有点模糊,但因为
missing
执行了 eager_load
操作,因此触发了错误,因为 preload
!= eager_load
,正如您引用的 PR 中提到的 “急切加载仍然是不支持”.
如果您查看文档了解
preload
与 eager_load
的区别,您可能会明白为什么为 preload
添加依赖于实例的范围是可行的,但对于 eager_load
ing 则不然,但如果不只是回复,我会进一步解释。