Search code examples
ruby-on-railsoverloadingmonkeypatching

Cannot override/monkey patch a rails method with rails 3.1.3


I am trying to override an active resource method like explained in this question : Remove .xml extension from ActiveResource request and this one : i want to use a REST api, i cannot manage to set active resource to use it

To do so i tested :

Creating in the /config/in itializers/ folder of my app a file named active_resource.rb with the following code :

class ActiveResource::Base   
  def element_path(id, prefix_options = {},query_options = nil)
  check_prefix_options(prefix_options)
  prefix_options, query_options = split_options(prefix_options) if query_options.nil?
  "#{prefix(prefix_options)}#{collection_name}/#{URI.parser.escape id.to_s}#{query_string(query_options)}"   
  end 
end

Adding the method inside my model. Here is my model code :

class Player < ActiveResource::Base
  def element_path(id, prefix_options = {}, query_options = nil)
    check_prefix_options(prefix_options)

    prefix_options, query_options = split_options(prefix_options) if query_options.nil?
    "#{prefix(prefix_options)}#{collection_name}/#{URI.parser.escape id.to_s}#{query_string(query_options)}"
  end
  self.site = "http://ws.maniaplanet.com/"
  self.user="**********"
  self.password="*********"
end

To validate the overriding of my custom code I have tried to use

puts  "called this method"

or

ActionController::Base.logger.info "called this method"

It has never worked.

Why can't i override the rails method element path ?

UPDATE

Tried to put active_resource.rb in extra after uncommenting the config.autoload_paths += %W(#{config.root}/extras) line in application.rb. No change

If i put the base.rb file with my class and method in lib/active_resource/ it breaks my app. I cannot launch rails server anymore


Solution

  • You should override class method, not instance one, so:

    class Player < ActiveResource::Base
    
      def self.element_path(id, prefix_options = {}, query_options = nil)
        #...
      end
    
    end
    

    That would be enough, if you going to make requests only from Player model.

    If you want this behaviour for any model, you should monkey patch ActiveResource::Base, again, the class method.

    # config/initializers/active_resource_patch.rb
    class ActiveResource::Base
    
      def self.element_path(id, prefix_options = {}, query_options = nil)
        #...
      end
    
    end