2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails】String#trメソッドで全角数字を半角に自動変換

2
Posted at

きっかけ

個人開発アプリ「えらぶノート」に、アイテム登録時の価格と容量について、全角数字だとエラーになるので半角数字で入力してもらうようメッセージがあるといいのではないか、という旨のフィードバックをいただきました。
(ありがとうございます!!)

フィードバックを受けて検討した結果、これを機に全角数字で入力されたものは半角に自動変換する機能を実装してみることにしました!!

半角変換の実装方法

全角→半角の変換にはString#trメソッドを使いました。

"120".tr("0-9", "0-9")
# => "120"

これで全角入力された数字を自動で半角に変換できます。

価格のように整数だけならこれで十分ですが、容量については、化粧品など極端に少ないもの(3.5gなど)の登録も想定しているため、小数点まで入力できるようになっています。
そのため、変換対象には全角の小数点も加える必要がありました。

"123.5".tr("0-9.", "0-9.")
# => "123.5"

全角の小数点もこのように指定しておくだけで、ちゃんと半角に変換されます。

ちなみに日本語(カタカナ⇆半角カタカナ、ひらがな⇆カタカナ変換など)を含む文字列の変換は、NKF(Network Kanji code conversion Filter)という標準ライブラリが使えそうです!

今回は数字と小数点のみを対象とするため、String#trメソッドの方が適していると判断しました。

いざ!実装

今回は価格(price)と容量(capacity)にコードを追加していきます。

最初はbefore_validationでまとめて変換しようと考えました。

app/models/item.rb
before_validation :normalize_price

def normalize_price
  self.price = self.price.to_s.tr("0-9.", "0-9.")
end

しかし、priceはinteger型、capacityはdecimal型のため、代入した瞬間にRailsがそれぞれの型に変換しようとします。
全角の「120」は数値として認識されず、00.0に変換されてしまいました。

item.price = "120"
item.capacity = "120"
item.price
# => 0
item.capacity
# => 0.0

そこで、値を代入する処理そのものであるprice=capacity=セッターを上書きし、代入されるタイミングで先に変換の処理が走るようにしました。

app/models/item.rb
class Item < ApplicationRecord
  def price=(value)
    super(zenkaku_to_hankaku(value))
  end

  def capacity=(value)
    super(zenkaku_to_hankaku(value))
  end

  private

  def zenkaku_to_hankaku(value)
    return value unless value.is_a?(String)
    value.tr("0-9.", "0-9.")
  end
end

全角数字を代入してみると、ちゃんと半角に変換されました!

item.price = "120"
item.capacity = "123.5"
item.price
# => 120
item.capacity
# => 123.5

まとめ

  • 数値のみの全角⇆半角変換には.trメソッドが良さそう。
  • 日本語を含む文字列の変換にはNKFが良さそう。
  • before_validationは保存直前に呼ばれるので、その前段階の代入時のセッターを上書きして対応した。

もっと良い書き方や、こうした方がいいよ!というご意見が
あれば、ぜひコメントで教えてください!

参考記事など

2
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?