Uploaded image for project: 'Mongoid'
  1. Mongoid
  2. MONGOID-3225

Use of polymorphic types causes criteria.where( :mongoidDoc => mongoidDoc) ) to fail

    • Type: Icon: Task Task
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 5.0.2
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None

      Greetings,

      I am writing up a "history" of actions taken for a piece of data. During this process I found that some polymorphic classes were not being properly searched for, possibly due to the initial base class not being aware of future object's relationships and not "massaging" the comparing value properly.

      I am using the master branch of a few days ago and this is not critical as it can be worked around.

      I've included test code that demonstrates the problem. I have simplified the code, as this was from a much larger code base.

      require 'mongoid'
      
      Mongoid.load!('config/mongoid.yml', :test)
      
      # A user of a system
      class User
        include Mongoid::Document
        field :email, :type => String
      end
      
      # the big container object
      class Book
        include Mongoid::Document
        embeds_many :notes, :class_name => 'Note', :inverse_of => :book
      end
      
      # the template "note"
      class Note 
        include Mongoid::Document
        embedded_in :book, :class_name => 'Book', :inverse_of => :notes
      end
      
      # a note that belongs to a user
      class UserNote < Note
        belongs_to :user, :class_name => 'User', :inverse_of => nil
        field :bar, :type => String
      end
      
      user = User.new email: 'joe@example.com'
      
      # set the book up
      book = Book.new
      note = UserNote.new({
        :user => user,
        :bar => 'abc',
      })
      book.notes << note
      
      # I was really expecting this code to work :)  <============================
      notes = book.notes.where(:user => user).all.to_a
      puts "testing: book.notes.where(:user => user)"
      if notes.count > 0
        puts "Does work\n\n"
      else
        puts "Does NOT work\n\n"
      end
      
      puts "testing: book.notes.where(:user_id => user.id)"
      notes = book.notes.where(:user_id => user.id).all.to_a
      if notes.count > 0
        puts "Does work\n\n"
      else
        puts "Does NOT work\n\n"
      end
      
      puts "Basic search test; to make sure where works"
      notes = book.notes.where(:bar => 'abc').all.to_a
      if notes.count > 0
        puts "Finding :bar = abc does work"
      end
      
      Unable to find source-code formatter for language: text. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      [deployer@local current]$ bundle exec ruby test.rb
      testing: book.notes.where(:user => user)
      Does NOT work
      
      testing: book.notes.where(:user_id => user.id)
      Does work
      
      Basic search test; to make sure where works
      Finding :bar = abc does work
      

      One possible solution is that as each new inherited object comes into existence, the relationships feed back into the parent's relations. Sounds a bit messy

      class UserNote < Note
        # this would, update Note.relations with a note that :user should be searched for as { user_id: => user.id }
        belongs_to :user, :class_name => 'User', :inverse_of => nil
      end
      

      Thank you!!!

      -daniel

            Assignee:
            durran.jordan@mongodb.com Durran Jordan
            Reporter:
            danlo danlo
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: