Correct syntax to call a mailer with interpolation

I have a method to dynamically call a mailer that look like this :

def mail
  application = mail[:application].capitalize
  class_template = mail[:template].split('/').[0]+ 'Mailer'
  template = mail[:template].split('/').second
  email_params = mail[:params]', ')

   # Here I have something like : "Application::TemplatetMailer.test_name(\"John\", \"Doe\").deliver_now"

How can I have something like :

Application::TemplatetMailer.test(\"John\", \"Doe\").deliver_now

instead of

"Application::TemplatetMailer.test(\"John\", \"Doe\").deliver_now"

>Solution :

You can look up arbitrary constants with constantize:

mailer = [ application, class_template ].join('::').constantize

mailer.send(template, *email_params).deliver_now

Be extremely careful with what access you allow to end users. Do not expose this in a way that allows them to make arbitrary method calls on arbitrary classes. Having an allow-list of classes and methods is way safer.

Leave a Reply