mongoid 忽略多态性

Polymorphism ignored by mongoid

一言以蔽之

我 运行 进入以下验证/模型保存错误

NameError (uninitialized constant PolymorphicAssociation):

背景和代码

考虑以下模型(省略Mongoid::Document

class User
  has_many :media_views

class MediaView
  field :last_seen_at, type: DateTime
  belongs_to :user
  belongs_to :media, polymorphic: true

class Image
  has_many :views, inverse_of :media, class_name: 'MediaView'

class Video
  has_many :views, inverse_of :media, class_name: 'MediaView'

我正在尝试通过服务

查找或更新现有MediaViews
# my_view_service.rb
class ViewService
  def initialize(user, media)
    @user = user
    @media = media
  end

  def just_viewed!
    set_view
    @view.last_seen_at = Time.now
    @view.save
  end

  def set_view
    @view = MediaView.where(
      user: @user,
      media: @media,
    ).first_or_initialize
  end

ViewService.new(User.first, Image.first).just_viewed!

将@view 保存后,我 运行 进入

NameError (uninitialized constant Media):

调试了好久,终于找到了

中的bug

gems/mongoid-6.0.0/lib/mongoid/relations/accessors.rb

type = @attributes[metadata.inverse_type] 为我的多态关联返回 nil 而不是 class 名称。

为什么 metadata.inverse_type(此处 media_type)为空?这真是个好问题。这与 MediaView 对象的构建方式有关。

我试图先使用

找到现有视图
@view = MediaView.where(
  user: @user,
  media: @media,
).first_or_initialize

问题是它没有设置多态关联的 _type 属性。我必须添加以下行

@view.media = @media unless @view.persisted?