我是Ruby和Ruby on Rails的初学程序员,我正在尝试在我的任务中运行rake命令,但是当我执行以下操作时:
rake daily_tasks:process_api
rake aborted!
ActiveRecord::AssociationTypeMismatch: Estado(#47392639701120) expected, got NilClass(#47392580444120)
/home/thiagoamaralr/Desktop/proponente-master-4f8a3b2ddb02a90b2c173cf31383505018d02dd/app/services/create_programa_api.rb:21:in `call'
/home/thiagoamaralr/Desktop/proponente-master-74f8a3b2ddb02a90b2c173cf31383505018d02dd/lib/tasks/daily_tasks.rake:7:in `block (3 levels) in <top (required)>'
/home/thiagoamaralr/Desktop/proponente-master-74f8a3b2ddb02a90b2c173cf31383505018d02dd/lib/tasks/daily_tasks.rake:5:in `each'
/home/thiagoamaralr/Desktop/proponente-master-74f8a3b2ddb02a90b2c173cf31383505018d02dd/lib/tasks/daily_tasks.rake:5:in `block (2 levels) in <top (required)>'
Tasks: TOP => daily_tasks:process_api
(See full trace by running task with --trace)
按照我正在尝试运行的任务:
namespace :daily_tasks do
desc "Process the day to day tasks"
task process_api: :environment do
SiconvApi::Programa.find.each do |programa|
if programa.data_inicio_recebimento_propostas && (programa.data_inicio_recebimento_propostas.to_date >= Date.parse("2015/06/01"))
CreateProgramaApi.call(SiconvApi::Serializers::Programa.new(programa))
end
end
end
end
这是内容create_programa_api.rb:
class CreateProgramaApi
def self.call(programa_api)
params = programa_api.to_h
params[:orgao] = Orgao.where("lower(name) = ?", programa_api[:orgao][:nome].mb_chars.downcase).first_or_create(name: programa_api[:orgao][:nome])
params[:orgao_vinculado] = Orgao.where("lower(name) = ?", programa_api[:orgao_vinculado][:nome].mb_chars.downcase).first_or_create(name: programa_api[:orgao_vinculado][:nome])
params[:orgao_executor] = Orgao.where("lower(name) = ?", programa_api[:orgao_executor][:nome].mb_chars.downcase).first_or_create(name: programa_api[:orgao_executor][:nome])
params[:estados] = []
if programa_api[:estados].size == 27
params[:estados] << Estado.find_by(sigla: 'Todos')
else
programa_api[:estados].each do |e|
params[:estados] << Estado.find_by(sigla: e)
end
end
params[:atendes] = [Atende.where("lower(name) = ?", programa_api[:atende_a].mb_chars.downcase).first_or_create(name: programa_api[:atende_a])] if programa_api[:atende_a]
params.delete(:atende_a)
programa = Programa.find_by(codigo: programa_api[:codigo])
if programa
programa.update(params)
else
Programa.create! params
end
end
end
感谢您的关注!
答案 0 :(得分:0)
nil
中有params[:estados]
个对象,Rails无法保存此关联。
删除它们的最简单方法是在第14行之后调用params[:estados].compact!
答案 1 :(得分:0)
这段代码是你的问题:
params[:estados] = []
if programa_api[:estados].size == 27
params[:estados] << Estado.find_by(sigla: 'Todos')
else
programa_api[:estados].each do |e|
params[:estados] << Estado.find_by(sigla: e)
end
end
如果未找到记录,#find_by
将返回nil
。这就是您收到错误的原因:
ActiveRecord::AssociationTypeMismatch: Estado(#47392639701120) expected, got NilClass
致电Programa.create!(params)
。
一种解决方案是在params[:estados].compact!
语句后调用if
(这是使用Array#compact!
删除任何nil
值。)
或者,您可以改为编写代码段,如下所示:
params[:estados] = Estadio.where(
sigla: (programa_api[:estados].size == 27 ? 'Todos' : programa_api[:estados])
)
使用此代码,不再需要调用compact!
,因为如果没有找到记录,我们最终会得到空数组(即没有{{1} }))。
请注意,此处的行为相当不相同 - 如果有多个nil
记录且Estado
等于sigla
之一,则会发生什么?还是programa_api[:estados]
?以前你只是获取“第一个”这样的记录,而现在你将获取所有。这可能不是问题(或者甚至可能是正确的行为!!) - 至少应该注意这一点。