使用Sidekiq Shopify Worker传递Devise current_user至Rails Job时缺失user_id报错
missing keyword: user_id的报错 我帮你分析下问题,这个报错的核心原因是你调用Active Job的方式不对,导致关键字参数没正确传递到Job的执行方法里,咱们一步步来修复:
问题根源
在你的OrderWebhooksController里,你直接调用了OrdersPaidJob.perform(...),但perform是Active Job的实例方法,不是类方法。直接通过类调用这个方法会绕过Active Job的参数序列化逻辑,导致你传入的user_id等关键字参数没有被正确绑定到perform方法的参数列表中,从而触发ArgumentError: missing keyword: user_id。
修复步骤
1. 修正Job的调用方式
把控制器里的perform替换成Active Job官方提供的类方法:如果是交给Sidekiq异步执行,用perform_later;如果需要同步执行,用perform_now。这里你用了Sidekiq,所以应该用perform_later:
# OrderWebhookController的orders_paid方法修改后 def orders_paid params.permit! # 替换perform为perform_later OrdersPaidJob.perform_later(shop_domain: shop_domain, webhook: webhook_params.to_h, user_id: current_user.id) head :no_content end
2. 额外注意:确认current_user的有效性
这里还有个潜在坑:Shopify的webhook是服务器对服务器的请求,没有用户会话上下文,所以current_user有可能是nil,这时候current_user.id会触发NoMethodError。你需要确认在webhook请求里是否真的能拿到有效的current_user,如果不行,建议通过shop_domain关联到对应的用户(比如你的Shop模型是否和User有关联?):
# 假设Shop模型有belongs_to :user的关联 def orders_paid params.permit! shop = Shop.find_by(shopify_domain: shop_domain) user_id = shop.user.id # 通过店铺关联到用户 OrdersPaidJob.perform_later(shop_domain: shop_domain, webhook: webhook_params.to_h, user_id: user_id) head :no_content end
验证修复
修改完成后重新触发webhook,Sidekiq应该就能正确接收参数并执行Job了。如果还有问题,可以查看Sidekiq的日志,确认参数是否被正确序列化传递。
内容的提问来源于stack exchange,提问作者Afolabi Olaoluwa

