Ruby 3.1升级后ElasticSearch导入模型出现Argument Error问题求助
解决Ruby 3.1升级后Elasticsearch导入任务的ArgumentError问题
问题根源
你推测的完全正确:Ruby 3.0+彻底分离了位置参数与关键字参数,而你使用的elasticsearch-model 6.1.1版本基于旧Ruby参数规则开发——它调用ActiveRecord的find_in_batches时,将哈希作为位置参数传递,但Ruby 3.1下Rails 6.1的find_in_batches要求接收关键字参数,因此触发了参数数量不匹配的ArgumentError。
不升级Elasticsearch的解决方案
方案1:给elasticsearch-model打参数兼容补丁
在项目的config/initializers目录下新建elasticsearch_patch.rb文件,添加以下代码修复代理类的参数传递逻辑:
module Elasticsearch module Model module Proxy def method_missing(name, *args, &block) # 针对find_in_batches等需要关键字参数的方法,将哈希转为关键字参数传递 if args.size == 1 && args.first.is_a?(Hash) && respond_to?(name) send(name, **args.first, &block) else super end end end end end
保存后重启Rails环境,再执行原导入命令即可。
方案2:自定义导入任务绕开原rake任务的参数问题
放弃官方通用导入rake任务,编写自定义任务显式控制参数传递:
在lib/tasks/elasticsearch_import.rake中添加:
namespace :elasticsearch do namespace :import do desc "Import ClinicalEquivalence records to Elasticsearch" task clinical_equivalence: :environment do puts "Starting ClinicalEquivalence import..." ClinicalEquivalence.__elasticsearch__.import(force: true) do |model| # 显式用关键字参数调用find_in_batches model.find_in_batches(batch_size: 1000) do |batch| yield batch end end puts "Import completed!" end end end
执行自定义任务替代原命令:
RAILS_ENV=development bundle exec rake elasticsearch:import:clinical_equivalence
方案3:使用ruby2_keywords兼容层快速修复
添加ruby2_keywords gem让旧代码的哈希参数在Ruby 3+下被识别为关键字参数:
- 在Gemfile中添加:
gem 'ruby2_keywords' - 执行
bundle install - 在
config/initializers/ruby2_keywords.rb中添加:require 'ruby2_keywords' module Elasticsearch module Model module Proxy ruby2_keywords :method_missing end end end
这个方案改动最小,适合快速解决问题,但会引入一个额外依赖。
内容的提问来源于stack exchange,提问作者Dev V
相关产品推荐
相关产品推荐

