2

我想要完成的是获取一个字符串,然后解析它,所以它只是数字。然后在显示它时,我将使用 number_to_phone 并且它们都是相同的。

到目前为止,我在我的模型中定义了这个:

  def parse_phone_nums
    self.main_phone = self.main_phone.gsub(/[.\-()\W]/, '') if self.main_phone
    self.alt_phone = self.alt_phone.gsub(/[.\-()\W]/, '') if self.alt_phone
    self.main_phone = "925" + self.main_phone if self.main_phone.length == 7
    self.alt_phone = "925" + self.alt_phone if self.alt_phone.length == 7
  end

并在我的控制器中调用它来创建和更新操作。我觉得这里好像有很多重复,并且想知道如何将代码减少到尽可能 DRY。

4

2 回答 2

2

许多可能的解决方案,大致:

def clean_up_phone(num)
  return unless num
  num = num.gsub(/[.\-()\W]/, '')
  num.length == 7 ? "925#{num}" : num
end

有多种方法可以使用此方法,包括自动设置、回调期间等。

我不确定正则表达式是您真正想要的,人们为电话号码输入了很多东西。您可能希望在验证之前对其进行更多处理,然后再添加区号。

于 2013-03-05T00:48:21.763 回答
0

我会选择这样的东西,因为它允许将来扩展(另一个区号?检测用户提交的区号等)并且易于测试。

而且由于很容易忘记用户可能使用的字符的匹配器,因此我将使用不同的方法从给定的字符串中提取数字。

def parse_phone_nums
  self.main_phone = parse_phone_number(self.main_phone) if self.main_phone
  self.alt_phone  = parse_phone_number(self.alt_phone)  if self.alt_phone
end

private

def parse_phone_number(string)
  number = extract_number(string)
  prefix_area_code(number)
end

def extract_number(string)
  characters = string.split("")
  characters.reduce("") { |memo, char| "#{memo}#{char}" if numeric?(char) }
end

def prefix_area_code(number)
  prefix = number.length == 7 ? "925" : ""
  "#{prefix}#{number}"
end

def numeric?(string)
  Float(string) != nil rescue false
end

理想情况下,我会将所有这些private方法提取到一个自己的类中,比如 PhoneNumberParser。

如果您认为def_phone_nums不够 DRY,或者您有更多电话号码,则应该可以:

def parse_phone_nums
  phones = %w[main alt]
  phones.each do |phone|
    current = self.send("#{phone}_phone")
    next unless current

    parsed = parse_phone_number(current)
    self.send("#{phone}_phone=", parsed)
  end
end
于 2013-03-05T02:55:00.410 回答