DEV Community

Waruna
Waruna

Posted on

Monkey patching on Ruby

Paperclip used to be a popular accessible file attachment library for ActiveRecord. However, with the introduction of ActiveStorage, its use case was replaced. It is now deprecated and does not support Ruby 3.0.

Recently, I had to work on an old Ruby on Rails app, migrating it from Ruby 2.7 to Ruby 3.0. However, moving all the paperclip logic to ActiveStorage was impossible, given the time and budget constraints.

But I was getting the following error:



undefined method escape' for URI:Module

module Paperclip
class UrlGenerator
  def escape_url(url)
    else
      URI.escape(url).gsub(escape_regex){|m| "%#{m.ord.to_s(16).upcase}" }
     end
   end
  end
end


Enter fullscreen mode Exit fullscreen mode

After researching, I found out this error happens because URI.escape was deprecated in Ruby 2.7 and removed in Ruby 3.0. This is where monkey patching comes in.
In Ruby, a Monkey Patch is a dynamic modification to a class, which means adding new or overwriting existing methods at runtime. Ruby provides this ability to give coders more flexibility.

To fix this, we can rewrite the escape_url method to use an alternative way to escape URLs, such as URI::DEFAULT_PARSER.escape or CGI.escape.

So, how would you do this? First, create a monkey patch file in the config/initializers directory. So it will be loaded when the project runs.



# config/initializers/paperclip_monkeypatch.rb

module Paperclip
  class UrlGenerator
    # Monkey patch to replace the deprecated URI.escape with URI::DEFAULT_PARSER.escape
    def escape_url(url)
      if url.respond_to?(:escape)
        url.escape
      else
        # Use URI::DEFAULT_PARSER.escape to handle the escaping
        URI::DEFAULT_PARSER.escape(url).gsub(escape_regex) { |m| "%#{m.ord.to_s(16).upcase}" }
      end
    end
  end
end


Enter fullscreen mode Exit fullscreen mode

URI::DEFAULT_PARSER.escape: This is the recommended alternative to URI.escape, which provides similar functionality for escaping URLs.

Restart Rails server to apply the change.

This should resolve the undefined method 'escape' error in Paperclip. I want to highlight that this is not a recommended method. It is only a quick solution, a bandage, so to speak. I'm planning to move this project to active storage as soon as possible, but this might come in handy for your hobby project or as a quick fix.

Top comments (0)