Search code examples
ruby-on-railsmongoidmongoid3counter-cache

Undefined method `reset_counters' for Mongoid 3.1.6


I just updated my mongoid to version 3.1.6, so that I could use the reset_counters method to keep track of my model relations. But just as I did before the gem update I still get this error:

undefined method `reset_counters' for Mongoid::Persistence::Atomic::Operation:Module

In my Gemfile I have this version:

gem 'mongoid', '3.1.6'

And Gemfile.lock states:

mongoid (3.1.6)
  activemodel (~> 3.2)
  moped (~> 1.4)
  origin (~> 1.0)
  tzinfo (~> 0.3.29)

Here is the model that should update the counters:

class Presentation
  include Mongoid::Document
  include Mongoid::Timestamps

  belongs_to :operation, :inverse_of => :presentations, :counter_cache => true

  after_save :update_counter

  def update_counter
    self.operation_id_change.each do |e|
      Operation.reset_counters(e, :presentations) unless e.nil?
    end
  end
end

And here is the model where the counter field is:

class Operation
  include Mongoid::Document
  include Mongoid::Timestamps

  field :presentations_count, type: Integer

  has_many :presentations, :inverse_of => :operation, dependent: :destroy
end

Solution

  • Looks like you just have a namespace problem. If you look at the error closely:

    undefined method ... for Mongoid::Persistence::Atomic::Operation:Module
    

    you'll see that it is complaining about not being able to find reset_counters in Mongoid::Persistence::Atomic::Operation, not Operation. And if you look at the 3.1.6 source, you'll find Operation in lib/mongoid/persistence/atomic/operation.rb.

    If you specify the fully qualified name for your Operation:

    def update_counter
      self.operation_id_change.each do |e|
        ::Operation.reset_counters(e, :presentations) unless e.nil?
      # ^^
      end
    end
    

    then it will call reset_counters on the right Operation module.