delayed_job_active_record: `Delayed::Job` no longer defined in initializers

We have some initializers in our app that do schedule recurring jobs if they are not scheduled yet (using the delayed_job_cron gem under the hood), so basically code like this:

# config/initializers/recurring_jobs.rb

if Delayed::Job.where('handler LIKE "%SomeRecurringJob%"').blank?
  Delayed::Job.enqueue(SomeRecurringJob.new, cron: '* * * * *')
end

Since 4.1.5 this results in NameError: uninitialized constant Delayed::Job. Looking at the changes it is very probably due to https://github.com/collectiveidea/delayed_job_active_record/pull/172 which changed the requireing of the relevant code to only happen after initialization.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 11
  • Comments: 16 (4 by maintainers)

Commits related to this issue

Most upvoted comments

I ran into this. This is a breaking change in a patch update. I’m not sure if the version numbers are locked to delayed_job but I definitely did not expect this update to break my app. I haven’t fully grokked #172 so maybe this is a good path forward but probably some warning and documentation about breaking changes and the pros/cons of different fixes might be warranted.

Yep, this seems to work for me:

# config/initializers/delayed_job_extensions.rb
module DelayedJobExtensions
  # my customizations
end

- Delayed::Job.prepend DelayedJobExtensions
+ Rails.application.configure do
+   config.after_initialize do
+     Delayed::Job.prepend DelayedJobExtensions
+   end
+ end

No errors and my customizations are available in the console. I think you could do something similar.

I think this may have caused the following in my app when I upgraded from 4.1.4 to 4.1.5 last night: undefined method `where’ for Delayed::Job:Class (NoMethodError) Did you mean? when. I’m adding this in case anybody else tries to search the error.

The error occurs in an initializer, so I added the block as suggested:

Rails.application.configure do
  config.after_initialize do
    # original code
  end
end

This seems to work (at least Rails will start now).

I forgot that change hadn’t been released. I need to circle back and update the changelog and probably add more documentation.

If you can, wrap what you need to run in an after_initialize like @ansonhoyt suggests, that will be the safest bet and your block will run after DJ’s because DJ’s is setup when the Bundler.require(*Rails.groups) runs in application.rb.

If you can’t use after_initialize,

require 'delayed/backend/active_record'
Delayed::Worker.backend = :active_record

will work, however make sure your initializer runs after any other ActiveRecord configuration initializers. The app initializers are usually run in alphabetical order by filename, so this can usually be accomplished by prefixing your initializer filename with z’s like zzzzz_my_late_run_intializer.rb. There are a number of ActiveRecord configuration items that won’t apply after ActiveRecord loading triggers and the rails team refuses to consider that a bug.

Ok. I was hoping to come up with a better solution, but didn’t, and time got away from me. I have pushed out 4.1.6 which only rolls back the loading change. Using after_initialize should not break with the update, but it will no longer be needed.

I would be nervous simply adding a require to your initializer. Looking at https://github.com/collectiveidea/delayed_job_active_record/pull/172, you’ll possibly reintroduce that issue to your app.

I have a similar problem. I’m configuring the reserve_sql_strategy option as detailed in the readme:

https://github.com/collectiveidea/delayed_job_active_record/blob/001b24687ca146581cb7b075f4353ea99ed51f70/README.md#L30

This has been working till version 4.1.5 where it produces an error:

/my-rails-app/config/initializers/delayed_job.rb:3:in `<top (required)>': undefined method `configuration' for Delayed::Backend::ActiveRecord:Module (NoMethodError)

Adding the require also resolves it.

This does seem related to the change in #172.