0

In a nutshell

I run into the following error with validations / model saving

NameError (uninitialized constant PolymorphicAssociation):

Background & code

Consider the following models (omitting 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'

I am trying to find or update existing MediaViews through a service

# 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!

Upon saving the @view I run into

NameError (uninitialized constant Media):

4

1 回答 1

0

After quite some time spent debugging, I finally found the bug in

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

The line type = @attributes[metadata.inverse_type] returned nil for my polymorphic association instead of the class name.

Why is metadata.inverse_type (here media_type) null ? That's a really good question. And it has to do with the way the MediaView object is built.

I was trying to find existing view first using

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

The problem with this, is that it does not set the _type attributes of the polymorphic association. I had to add the following line

@view.media = @media unless @view.persisted?
于 2016-12-12T22:05:27.557 回答