mongoid / mongoid-history

Multi-user non-linear history tracking, auditing, undo, redo for mongoid.
https://rubygems.org/gems/mongoid-history
MIT License
393 stars 129 forks source link

undefined method `[]' for #<..::EmbedsMany> #219

Closed moddx closed 6 years ago

moddx commented 6 years ago

I'm trying to use mongoid-history, but I'm confronted with the following error message when trying to save an object. Disabling mongoid-history lets me save my objects just fine.

undefined method `[]' for #

I am running Rails 5.2.0 on ruby 2.5.1, together with mongoid 7.0.0 and mongoid-history 0.8.0.

Following are my models:

class Recipe
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::History::Trackable

  field :name, type: String
  field :intro, type: String
  field :quantity, type: String
  field :instructions, type: String
  field :tags, type: Array, default: []

  embeds_many :ingredients
  accepts_nested_attributes_for :ingredients, :allow_destroy => true

  track_history on: [:fields, :embedded_relations],
                :modifier_field => :modifier,
                :modifier_field_inverse_of => :nil,
                :version_field => :version,
                :track_create   =>  true,
                :track_update   =>  true,
                :track_destroy  =>  true

  def tags_list=(arg)
    self.tags = arg.split
  end

  def tags_list
    self.tags.join(' ')
  end
end
class Ingredient
  include Mongoid::Document
  field :quantity, type: String
  field :unit, type: String
  field :name, type: String
  embedded_in :recipe, :inverse_of => :ingredients
end
class User
  include Mongoid::Document
  include Mongoid::Timestamps
  include ActiveModel::SecurePassword

  field :name, type: String
  field :email, type: String
  field :password_digest, type: String
  field :active, type: Mongoid::Boolean
  field :restricted, type: Mongoid::Boolean
  field :avatar, type: BSON::Binary

  has_secure_password
  validates_presence_of :password, :on => :create

  index({ name: 1 }, { unique: true, name: 'name_idx' })
end

Doing something like the following results in the above mentioned error:

user = User.first
recipe = Recipe.first
recipe.name = "Something Else"
recipe.modifier = user
recipe.save

Might just be an configuration issue, but I can't figure out what's wrong.

dblock commented 6 years ago

That's probably because support for mongoid 7 hasn't been added. Care to PR it? Start by adding to .travis.yml and seeing what breaks? Also we should lock things down to mongoid < 8 to avoid similar problems in the future.

dblock commented 6 years ago

I opened https://github.com/mongoid/mongoid-history/issues/220 too.

moddx commented 6 years ago

I started to do what you proposed and solved a few things, including the error message from above, but am now stuck with the following error.

Mongoid::History::Trackable MyInstanceMethods #modified_attributes_for_create embeds_one when obj soft-deleted 
       Failure/Error: relation_of(field) == Mongoid::Relations::Embedded::One

       NameError:
         uninitialized constant Mongoid::Relations
       # ./lib/mongoid/history/trackable.rb:319:in `embeds_one?'
       # ./lib/mongoid/history/options.rb:145:in `categorize_tracked_option'
       # ./lib/mongoid/history/options.rb:100:in `block in parse_tracked_fields_and_relations'
       # ./lib/mongoid/history/options.rb:97:in `each'
       # ./lib/mongoid/history/options.rb:97:in `parse_tracked_fields_and_relations'
       # ./lib/mongoid/history/options.rb:19:in `prepared'
       # ./lib/mongoid/history/trackable.rb:509:in `history_trackable_options'
       # ./lib/mongoid/history/trackable.rb:428:in `tracked_fields'
       # ./lib/mongoid/history/trackable.rb:420:in `tracked_fields_for_action'
       # ./lib/mongoid/history/trackable.rb:394:in `tracked_field?'
       # ./lib/mongoid/history/attributes/create.rb:8:in `block in attributes'
       # ./lib/mongoid/history/attributes/create.rb:7:in `each'
       # ./lib/mongoid/history/attributes/create.rb:7:in `attributes'
       # ./lib/mongoid/history/trackable.rb:215:in `modified_attributes_for_create'
       # ./spec/unit/my_instance_methods_spec.rb:136:in `block (5 levels) in <top (required)>'
       # ./vendor/bundle/ruby/2.5.0/gems/rspec-support-3.7.1/lib/rspec/support/reentrant_mutex.rb:23:in `synchronize'
       # ./spec/unit/my_instance_methods_spec.rb:156:in `block (6 levels) in <top (required)>'
       # ./vendor/bundle/ruby/2.5.0/gems/rspec-core-3.7.1/exe/rspec:4:in `<main>'

I don't have much experience with ruby and gem development, and don't really now how to fix this. Mongoid::Relations::Embedded seem to be nested namespaces, and One is a class. When Mongoid::Relations is not initialized, does that mean that an include, gem or other config option is missing?

dblock commented 6 years ago

Maybe Mongoid7 changed the class names? Check what relation_of(field) returns now?

dblock commented 6 years ago

Btw, Donate $50 to my charity and I can take care of it :)

moddx commented 6 years ago

Yes, it seems they have restructured and renamed the Mongoid::Relations module. The stuff is now in Mongoid::Association::Embedded::..

Just found the current API doc after searching for it quite a lot. https://www.rubydoc.info/github/mongoid/mongoid/ still referred to some old version, but mentions that its the doc for the master branch of mongodb/mongoid. Also just found the 'Reload this project' button on rubydocs which did the trick.

50$ can't outweight what I'm learning through doing this. But I might donate anyway :)

dblock commented 6 years ago

Dup for https://github.com/mongoid/mongoid-history/issues/220, there’s a PR too :)