从 Ruby 2.7 更新到 Ruby 3.0.1 后出现 ArgumentError
ArgumentError after updating from Ruby 2.7 to Ruby 3.0.1
更新 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)
如何解决错误 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
正如您分享了 link 关于 Ruby 3 中的变化,答案就在 link 本身:
Separation of positional and keyword arguments in Ruby 3.0:
In most cases, you can avoid incompatibility by adding the double splat operator. It explicitly specifies passing keyword arguments instead of a Hash object. Likewise, you may add braces {} to explicitly pass a Hash object, instead of keyword arguments.
现在查看您正在执行的代码:
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_domain
和 webhook
是必需的关键字参数,并且您传递的是单个参数,因为 Ruby 现在将散列视为单个参数而不是关键字参数,直到您添加双 splat 运算符。
更新 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)
如何解决错误 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
正如您分享了 link 关于 Ruby 3 中的变化,答案就在 link 本身:
Separation of positional and keyword arguments in Ruby 3.0:
In most cases, you can avoid incompatibility by adding the double splat operator. It explicitly specifies passing keyword arguments instead of a Hash object. Likewise, you may add braces {} to explicitly pass a Hash object, instead of keyword arguments.
现在查看您正在执行的代码:
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_domain
和 webhook
是必需的关键字参数,并且您传递的是单个参数,因为 Ruby 现在将散列视为单个参数而不是关键字参数,直到您添加双 splat 运算符。