Ruby If语句重构

时间:2019-08-23 08:01:31

标签: ruby

很长一段时间后,我要回到Ruby。

我写了下面的功能代码:

def generate_address_record(data)
 address = FM[:fap_address].build do |a|
        if data['Line 1'].blank?
          a.unstructured_address.line1 = nil
        else
          a.unstructured_address.line1 = data['Line 1']
        end

        if data['Line 2'].blank?
          a.unstructured_address.line2 = nil
        else
          a.unstructured_address.line2 = data['Line 2']
        end

        if data['Line 3'].blank?
          a.unstructured_address.line3 = nil
        else
          a.unstructured_address.line3 = data['Line 3']
        end

        if data['Line 4'].blank?
          a.unstructured_address.line4 = nil
        else
          a.unstructured_address.line4 = data['Line 4']
        end

        if data['Line 5'].blank?
          a.unstructured_address.line5 = nil
        else
          a.unstructured_address.line5 = data['Line 5']
        end

        if data['Postcode'].blank?
          a.unstructured_address.postcode = nil
        else
          a.unstructured_address.postcode = data['Postcode']
        end
  end
end

有没有一种方法可以在一个循环中以“更精细”的方式重写它,因此我不需要所有这些单独的if语句。

任何建议将不胜感激。

4 个答案:

答案 0 :(得分:2)

是的,您可以使用#presence(我假设您使用的是Rails):

a.unstructured_address.line1 = data['Line 1'].presence

#presence行为:

''.presence
# => nil
nil.presence
# => nil
'a'.presence
# => "a"
false.presence
# => nil

答案 1 :(得分:2)

如果data仅包含期望值,则可以将键转换为方法名称。

def generate_address_record(data)
  address = FM[:fap_address].build do |a|
      data.each do |key, value|
          name = key.gsub(/[[:space:]]/, '').downcase
          a.unstructured_address.public_send("#{name}=", value.presence)
      end
  end
end

当哈希键来自应用程序外部或其他不受控制的环境时,请小心(或不要使用此方法)。

答案 2 :(得分:2)

我建议将已发布的各种解决方案结合起来,因为我认为它在简短性和可读性之间具有很好的平衡:

def generate_address_record(data)
  address = FM[:fap_address].build do |a|
    a.unstructured_address.line1    = data['Line 1'].presence
    a.unstructured_address.line2    = data['Line 2'].presence
    a.unstructured_address.line3    = data['Line 3'].presence
    a.unstructured_address.line4    = data['Line 4'].presence
    a.unstructured_address.line5    = data['Line 5'].presence
    a.unstructured_address.postcode = data['Postcode'].presence
  end
end

答案 3 :(得分:0)

我发现有用的一种模式是进行哈希处理,然后对其进行迭代:

def generate_address_record(data)
   address = FM[:fap_address].build do |a|
     {
       "Line 1" =>  :line1, 
       "Line 2" =>  :line2,
       "Line 3" =>  :line3,
       "Line 4" =>  :line4,
       "Line 5" =>  :line5,
       "Postcode" => :postcode
     }.each do |key, accessor|
       if data[key].blank?
         a.unstructured_address.send(accessor) = nil
       else
         a.unstructured_address.send(:"#{accessor}=") = data[key]
       end
     end
  end
end

您也可以将presence与mrzasa共享一起使用