ruby on rails - ActiveRecord::AssociationTypeMismatch gotNil



我是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_program_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

感谢您的关注!

params[:estados]中有nil对象,Rails无法保存此关联。删除它们的最简单方法是在第14行之后调用params[:estados].compact!

这段代码是您的问题:

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)

一种解决方案是在if语句之后调用params[:estados].compact!(这是使用Array#compact!来移除任何nil值)。

或者,你可以写这样的代码:

params[:estados] = Estadio.where(
  sigla: (programa_api[:estados].size == 27 ? 'Todos' : programa_api[:estados])
)

有了这个代码,就不再需要调用compact!了,因为如果找不到记录(即没有nil值),我们已经得到了一个空的数组。

请注意,这里的行为并不完全相同-如果有多个Estado记录的sigla等于programa_api[:estados]'Todos'中的一个,会发生什么?以前您只获取"第一个"这样的记录,而现在您将获取所有。这可能不是问题(甚至可能是正确的行为!!)——至少这只是需要注意的事情。

相关内容

  • 没有找到相关文章

最新更新