【问题标题】:ArgumentError after updating from Ruby 2.7 to Ruby 3.0.1从 Ruby 2.7 更新到 Ruby 3.0.1 后的 ArgumentError
【发布时间】:2021-07-20 04:59:29
【问题描述】:

将 ruby​​ 更新到 3.0.1 后,非常简单的代码无法执行 app_uninstalled_job.rb

class AppUninstalledJob < ActiveJob::Base
  def perform(shop_domain:, webhook:)
    shop = Shop.find_by(shopify_domain: shop_domain)

有错误

Error performing AppUninstalledJob (Job ID: ***) from Async(default) in 0.18ms: ArgumentError (wrong number of arguments (given 1, expected 0; required keywords: shop_domain, webhook)):
.../app/jobs/app_uninstalled_job.rb:2:in `perform'

正确接收到的数据

Started POST "/webhooks/app_uninstalled" for 34.69.74.99 at 2021-07-20 04:44:31 +0000
Processing by ShopifyApp::WebhooksController#receive as */*
  Parameters: {"id"=>876876876, "name"=>"shopname", "email"=>"***@gmail.com", "domain"=>"shop.myshopify.com", "province"=>.....}}
[ActiveJob] Enqueued AppUninstalledJob (Job ID: ) to Async(default) with arguments: {:shop_domain=>"shop.myshopify.com", :webhook=>{"id"=>876876876, "name"=>"shop", "email"=>"***@gmail.com", "domain"=>"shop.myshopify.com", "province"=>....}


[ActiveJob] [AppUninstalledJob] [****9] Performing AppUninstalledJob (Job ID: **99) from Async(default) enqueued at 2021-07-20T04:44:31Z with arguments: {:shop_domain=>"shop.myshopify.com", :webhook=>{"id"=>876876876, "name"=>"shop", "email"=>"***@gmail.com", "domain"=>"shop.myshopify.com", "province"....}
Completed 200 OK in 6ms (ActiveRecord: 0.0ms | Allocations: 2327)

与处理参数委托https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/有关

如何解决错误ArgumentError(参数数量错误(给定1,预期0;必需关键字:shop_domain,webhook)

更新:webhook 控制器的代码

module ShopifyApp
  class MissingWebhookJobError < StandardError; end

  class WebhooksController < ActionController::Base
    include ShopifyApp::WebhookVerification

    def receive
      params.permit!
      job_args = { shop_domain: shop_domain, webhook: webhook_params.to_h }
      webhook_job_klass.perform_later(job_args)
      head(:ok)
    end

    private

    def webhook_params
      params.except(:controller, :action, :type)
    end

    def webhook_job_klass
      webhook_job_klass_name.safe_constantize || raise(ShopifyApp::MissingWebhookJobError)
    end

    def webhook_job_klass_name(type = webhook_type)
      [webhook_namespace, "#{type}_job"].compact.join('/').classify
    end

    def webhook_type
      params[:type]
    end

    def webhook_namespace
      ShopifyApp.configuration.webhook_jobs_namespace
    end
  end
end

【问题讨论】:

  • 能否请您添加此操作的代码:ShopifyApp::WebhooksController#receive
  • @Deepesh 代码已添加,感谢您的帮助
  • 这可能是一个“旧”工作(你使用旧的 ruby​​ 排队并且仍然存在于你的 redis 中的工作)?您现在尝试的新工作是否会发生这种情况?
  • 解决方案在您的问题本身(链接),添加双 splat 运算符:webhook_job_klass.perform_later(**job_args)
  • @SagarRanglani 他可能已经猴子修补了方法。

标签: ruby-on-rails ruby shopify-app


【解决方案1】:

正如您分享了有关 Ruby 3 更改的链接,答案就在链接本身中:

Ruby 3.0 中位置参数和关键字参数的分离:

在大多数情况下,您可以通过添加双 splat 运算符来避免不兼容。它明确指定传递关键字参数而不是 Hash 对象。同样,您可以添加大括号 {} 来显式传递 Hash 对象,而不是关键字参数。

现在查看您正在执行的代码:

job_args = { shop_domain: shop_domain, webhook: webhook_params.to_h }
webhook_job_klass.perform_later(job_args)

即,将哈希传递给方法,而不是您打算传递关键字参数,您可以通过添加双 splat 运算符来修复:

webhook_job_klass.perform_later(**job_args)

有关错误的更多信息:

错误是:

ArgumentError (wrong number of arguments (given 1, expected 0; required keywords: shop_domain, webhook)):

这意味着 shop_domainwebhook 是必需的关键字参数,并且您正在传递单个参数,因为 Ruby 现在将哈希视为单个参数而不是关键字参数,直到您添加双 splat 运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 2021-10-13
    • 1970-01-01
    • 2014-10-20
    相关资源
    最近更新 更多