DRYing up method calls in rails

Solution 1:

The main problem here is the architecture of your mailer class & methods. Do you really need three different mail methods or can this get DRYed?

You can pass in the days and template name

class Mailer < ApplicationMailer
  def fun(id, day_count)
    user = User.find(id)
    template = "fun_#{day_count}days"

    mail(:to => "#{@user.name} <#{@user.email}>", 
     :subject => "Fun #{days}", 
     :template_name => template)
  end
end

and in your main function you can do

def main_fun(data)
  id = data[0]
  day = data[1]
    
  Mailer.fun(id, day).deliver_now
end

Meta programming like send / public_send is a powerful tool if you develop a e.g. library but in this case it makes the code harder to understand and maintain. This change also makes the code easier to extend. In case you want to introduce a 4 days mail, you only need to add another template for it and no need to c&p another method in the mailer class.