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

大まかに、多くの可能な解決策の1つ:

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 に抽出します。

DRY が十分ではないと思われる場合def_phone_nums、またはもっと多くの電話番号を持っている場合は、これでうまくいくはずです:

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 に答える