Search code examples
ruby-on-railsactiverecorddelayed-jobbefore-filter

Delayed job; does it skip before filter


I have a delayed job that runs perfect against a public schema in postgresql.
Most of my operations however are against other schemas (one for each client)

To handle different schemas I've followed the instructions and put code to switch search path, in my before_filter (in application controller).

I've noticed. That the code in the before_filter gets called perfectly during typical operations, but not at all during delayed job.

I trimmed and trimmed out everything but the simplest thing I could think of, to show entrance.

class ApplicationController < ActionController::Base
  protect_from_forgery

  def write_to_log(text)
    File.open('c:\temp.txt', 'ab') do |f|
      f.write text + "\r\n"
      f.close
    end
  end
  before_filter :on_before_filter
  def on_before_filter
    write_to_log('hey dave');
    return if(use_token() == false);
    set_active_schema if(goto_log_in? == false);
  end

The code in the worker class

def run_job(id)
  upload = Upload.find(id)
  upload.run_job();
end
handle_asynchronously :run_job, :priority => 10, :queue => 'public'  

Quite standard stuff? Though the code in the job runs, the before_filter code doesn't get called.

So my question is. Did I do something wrong? Or more importantly, how can I do something right?


Solution

  • I'm not recommending this approach; I'm just answering your question by providing this code. Since you essentially want your code to run before any attempted call to the database, you can monkey patch ActiveRecord. Add the following code to config/initializers/active_record_monkey_patch.rb

    class ActiveRecord::ConnectionAdapters::ConnectionPool
      # create an alias for the old 'connection' method
      alias_method :old_connection, :connection
    
      # redefine the 'connection' method
      def connection
        # output something just to make sure the monkey patch is working
        puts "*** custom connection method called ***"
    
        # your custom code is here
        write_to_log('hey dave');
        return if(use_token() == false);
        set_active_schema if(goto_log_in? == false);
    
        # call the old 'connection' method
        old_connection
      end
    
    end
    

    You'll see your custom connection method getting called frequently now, and it will work without a controller. You can test it by opening up a rails console and performing any database query, and you should see the "custom connection method called" message displayed several times.