zoonoo
zoonoo

Reputation: 535

Ruby on Rails: How can I override a method from a gem while calling the super method

Mongoid::Persistable::Creatable::ClassMethods.module_eval do
  def create(attributes = nil, &block)
    begin
      super
    rescue Mongo::Error::OperationFailure => e
      Rails.logger.error "failed to create notifications #{e.message}, #{e.backtrace}"
      raise
    end
  end
end

Hello all, I'm trying to override a method from mongoid gem. So I've implemented the above method in config/initializers/mongo.rb, expecting my create method to run as defined in the gem, while leaving error log in case it there is a Mongo::Error::OperationFailure. But instead it gives me this error.

[1] pry(main)> Notification.create(id: 'ididididididid')
NoMethodError: super: no superclass method `create' for Notification:Class

I would like to know why this error occurs and how I can fix it. Thank you.

Upvotes: 1

Views: 818

Answers (1)

ndnenkov
ndnenkov

Reputation: 36110

Monkey patching it directly is hacky and overwrites the method altogether. You expected super to call the original implementation, but it is no longer there. Instead create a new module and include it there:

module CreateWithErrorLogging
  def create(attributes = nil, &block)
    begin
      super
    rescue Mongo::Error::OperationFailure => e
      Rails.logger.error "failed to create notifications #{e.message}, #{e.backtrace}"
      raise
    end
  end
end

Mongoid::Persistable::Creatable::ClassMethods.include CreateWithErrorLogging

Upvotes: 7

Related Questions