You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OAuth2认证后ActiveJob报'Uninitialized Constant GuestsCleanupJob'错误求助

问题:ActiveJob执行失败提示"uninitialized constant GuestsCleanupJob"

我在Rails 7 + Ruby 3.x环境下,通过ActionCable在用户OAuth2认证完成后广播JWT令牌,为了先重定向客户端到登录页再广播,设置了认证后延迟执行广播。发送Devise邮件的ApplicationJob可正常运行,但自定义的GuestsCleanupJob一直报错。


现有代码

ApplicationJob(app/jobs/application_job.rb)

class ApplicationJob < ActiveJob::Base
  queue_as :mailers

  def perform(devise_mailer, method,user_id, *args)
    user = User.find(user_id)
    devise_maier.send(method,user,*args).deliver_now
  end

end

OmniauthCallbacksController的google_oauth2方法(app/controllers/users/omniauth_callbacks_controller.rb)

def google_oauth2
  # You need to implement the method below in your model (e.g. app/models/user.rb)
  @user = User.from_omniauth(request.env['omniauth.auth'])
  if @user.persisted?
    flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: 'Google'        
    sign_in @user, event: :authentication #this will throw if @user is not activated
    token = Warden::JWTAuth::UserEncoder.new.call(@user, :user, nil)[0].to_s                           
    binding.pry
    GuestsCleanupJob.set(wait: 2.second).perform_now(token)
    redirect_to "http://127.0.0.1:3002/", allow_other_host: true  
  else
    session['devise.google_data'] = request.env['omniauth.auth'].except('extra') # Removing extra as it can overflow some session stores
    redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n")
  end
end

GuestsCleanupJob(app/jobs/guests_cleanup_job.rb)

class GuestsCleanupJob < ApplicationJob
  queue_as :default

  def perform(token)
    ActionCable.server.broadcast "ChatChannel", {"type":"token","token":"Bearer #{token}"}       
  end
end

问题现象

  • 执行后错误日志显示uninitialized constant GuestsCleanupJob
  • 尝试为Job添加Jobs命名空间后,报错uninitialized constant Jobs

解决步骤

1. 确认文件路径与命名规范

Rails对ActiveJob的文件命名有严格约定:

  • 类名GuestsCleanupJob对应的文件必须是app/jobs/guests_cleanup_job.rb(下划线命名,与类名驼峰一一对应)
  • 检查文件是否确实放在app/jobs目录下,文件名无拼写错误

2. 重启Sidekiq服务器

Rails开发环境下,新增的Job文件不会自动加载到Sidekiq进程中。修改或新增Job后,必须重启Sidekiq才能让它识别新的Job类。

3. 替换perform_now为perform_later(关键修复)

当前调用的GuestsCleanupJob.set(wait: 2.second).perform_now(token)存在逻辑错误:perform_now是同步执行,会忽略延迟设置且不会放入Sidekiq队列。延迟执行必须用perform_later:

# 错误写法
GuestsCleanupJob.set(wait: 2.second).perform_now(token)

# 正确写法
GuestsCleanupJob.set(wait: 2.second).perform_later(token)

perform_later才会将Job放入Sidekiq队列异步执行,符合你延迟广播的需求。

4. 规范命名空间(若需使用)

如果一定要用Jobs命名空间:

  • 创建app/jobs/jobs目录,将Job文件放在app/jobs/jobs/guests_cleanup_job.rb
  • 类定义需包含模块声明:
module Jobs
  class GuestsCleanupJob < ApplicationJob
    queue_as :default

    def perform(token)
      ActionCable.server.broadcast "ChatChannel", {"type":"token","token":"Bearer #{token}"}       
    end
  end
end
  • 调用时需写全命名空间:Jobs::GuestsCleanupJob.set(wait: 2.second).perform_later(token)
    若无特殊需求,不建议额外添加命名空间,保持默认顶层类更简洁。

5. 检查自动加载配置(可选)

在config/application.rb中确认自动加载路径包含app/jobs(Rails 7默认已配置,除非手动修改过):

config.autoload_paths << Rails.root.join('app/jobs')

生产环境下需运行rails assets:precompile或重启服务器确保类加载。


内容的提问来源于stack exchange,提问作者Moin Ahmed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 21:23:26