Search code examples
sinatrahamlrufus-schedulerpony

Undefined method `haml' when rendering haml in Pony mail from scheduled job


I have a sinatra app that executes cucumber tests and sends email notification with their results. Email gem is Pony, and there is a haml template for this notification.

This logic works within a route:

require 'sinatra'
require 'haml'
require 'pony'

get "/execute_all/?" do
  execute_all_tests()
  Pony.mail :to => "[email protected]",
      :from => "[email protected]",
      :subject => "Test results,
      :html_body => haml(:email_layout)

      redirect "/"

end

However when I use scheduled job with rufus scheduler for these actions, I get following exception:

scheduler caught exception:
undefined method `haml' for main:Object

Code is copypasta from route:

   scheduler = Rufus::Scheduler.start_new
   scheduler.every '2h' do
      execute_all_tests()
      Pony.mail :to => "[email protected]",
          :from => "[email protected]",
          :subject => "Test results,
          :html_body => haml(:email_layout)
   end

All two methods are in the same file, that is executed to run Sinatra app.

How to get rid of this exception, and send emails with haml template as scheduled job?


Solution

  • The haml method is only available in the context of a request to Sinatra (it is an instance method on Sinatra::Base), and it can’t be used outside of a Sinatra request.

    In order to render a Haml template, you can use the Haml API directly:

    haml_template = File.read(File.join(settings.views, 'email_layout.haml'))
    
    scheduler = Rufus::Scheduler.start_new
      scheduler.every '2h' do
        execute_all_tests()
        Pony.mail :to => "[email protected]",
          :from => "[email protected]",
          :subject => "Test results",
          :html_body => Haml::Engine.new(haml_template).render(binding)
      end
    end
    

    Here I’m assuming execute_all_tests is using instance variables that are referenced in the Haml template, so we pass the binding to the Haml render method to access these variables. You might also need to pass in any Haml options you need as the second parameter to new.