Adding Methods & Monkey Patching in Ruby on Rails
Do you ever want your own methods in Ruby's libraries? Sometimes it comes to me that "what if I have xxx method and it will be great." In fact, since Ruby offers a way to add or overwrite methods in existing libraries, it is easy to do it in Rails.
One good example is when we're checking if a Date
is weekday or weekend. It's great that we're able to use #wday
and get the weekday of a specific date.
date = Date.new(2016, 4, 11)
date.wday # => 1
So we can define two methods that checks if a date is weekday or weekend.
def weekend?(date)
[6, 0].include?(date.wday)
end
def weekday?(date)
!weekend?(date)
end
date = Date.new(2016, 4, 11)
weekday?(date) # => true
However, this is very limited because we still have to use an argument in the method. We can put it in the Date
class then we can get rid of the argument.
class Date
def weekend?
[6, 0].include?(self.wday)
end
def weekday?
!weekend?
end
end
date = Date.new(2016, 4, 11)
date.weekday? # => true
It looks a lot better. But where should we put it in a Rails project? The best place is /lib
since it serves to hold anything that is not domain-specific in your project. Creating a lib/patch
directory and puts a date.rb
file like:
- lib
- patch
- date.rb
And then we load the files every time we start the Rails server or console. In config/initializers
we create a patch.rb
file that looks like:
Dir["#{Rails.root}/lib/patch/**/*.rb"].each {|file| require file }
And we're done! Any other patch we want to create for other class or libraries can be put in lib/patch
directory too.