如何在Rails中无错误地访问嵌套变量

如果我具有以下结构的参数:

data = {
  "messageId" => "B2YAx4rSMTZ4D8FJs1hsoV","eventId" => "appointmentBooking.cancelled","eventSchemaVersion" => 1.0,"eventInstanceOriginationDateTime" => "2019-11-06T19:24:10Z","eventData" => {
    "siteId" => 232,"appointmentId" => 48761
  },"subdomain" => "api","consultation" => {}
}

我想访问siteIdappointmentId以获得另一个功能,我发现自己正在执行以下操作:

data = params['eventData']

if data.present?
  siteID = data['siteId']
  appointmentID = data['appointmentId']
end

if siteID and appointmentID
  # process this
end

有时可以使用,但是如果!data.present?siteIDappointmentID未定义,并且最后一次if调用将引发错误:

NameError (undefined local variable or method `siteID'

是否有更好的方法可以做到而无需在data = params['eventData']之后直接预定义变量?

qq34589355 回答:如何在Rails中无错误地访问嵌套变量

您可以使用dig方法。如果任何中间步骤是nil,它将返回nil

appointment_id = data.dig('eventData','appointmentId')
#=> 48761

site_id = data.dig('eventData','siteId')
#=> 232

然后

if site_id && appointment_id
  # do_something
end
,

您可以显式检查您希望存在的属性,然后一次性设置var和过程:

data = params['eventData']

if data && data['siteId'] && data['appointmentId']
  siteID = data['siteId']
  appointmentID = data['appointmentId']
  # process this
end

另一种选择是将if语句结果保存到它自己的var中,然后将其用作处理的条件:

data = params['eventData']

process = if data.present?
  siteID = data['siteId']
  appointmentID = data['appointmentId']
end

if process
  # process this
end

或者另一个选择是将vars设置为内联:

data = params['eventData']

if data && siteID = data['siteId'] && appointmentID = data['appointmentId']
  # process here
end
,

我们可以编写以下方法:

def extract(schedule)
  siteId,appointmentId = 
    schedule["eventData"]&.values_at("siteId","appointmentId")
end

如果schedule没有键"eventData",则sideIdappointentId都被赋值为nil。如果schedule确实有密钥"eventData",则我假设schedule["eventData"]是一个散列,并且:

siteId = schedule["eventData"]["siteId"]
appointmentId = schedule["eventData"]["appointmentId"]

&safe navigation operator,它在Ruby v2.3中首次亮相。另请参见Hash#values_at

此方法的用法如下。

def doit(schedule)
  siteId,appointmentId = extract(schedule)
  if siteId && appointmentId
    # do something
  else
    # do something else
  end
end

以下是extract返回的值的一些示例:

schedule = { "eventData"=>{ "siteId"=>232,"appointmentId"=>48761 } }
siteId,appointmentId = extract(schedule)
  #=> [232,48761] 
siteId
  #=> 232 
appointmentId
  #=> 48761 

schedule = { "eventData" => { "siteId" => 232 } }
siteId,nil] 

schedule = { "eventData" => {} }    
siteId,appointmentId = extract(schedule)
  #=> [nil,nil] 
本文链接:https://www.f2er.com/3149307.html

大家都在问