ユーザーにデータを入力してもらう際に、保存する内容(形式)を統一したいなと思った時に下記の設定が役に立ちました。
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
before_validation :normalize_attributes
private
def normalize_attributes
attributes.each do |key, value|
if value.is_a?(String)
self[key] = value.tr("0-9", "0-9").gsub(/[\s ]+/, "")
end
end
end
end
処理の内容
attributes.each do |key, value|
attributes.each は、モデルのすべての属性(カラム)とその値をハッシュの形で取得するためのものです。attributes は ActiveRecord モデルに含まれているメソッドで、モデルに対応するデータベーステーブルの各カラム名と、そのレコードの値をキーと値のペアとして返します。
具体的に言うと、Employee や Company などのモデルに attributes.each を使うと、そのインスタンスのすべてのカラムと現在の値を取得できるため、各カラムごとに変換や処理が可能になります。
例えば、Employee モデルで以下のようなカラムがあった場合
Employeeモデル
class Employee < ApplicationRecord
# カラム: name, phone_number, address, company_id
end
あるレコードが以下のようなデータを持っているとします:
employee = Employee.find(1)
employee.attributes #=> { "id" => 1, "name" => "田中 太郎", "phone_number" => "000 111222333", "address" => "東京" }
この場合、attributes.each を使うと id, name, phone_number, address, company_id とその値を順に取り出して処理できます。
if value.is_a?(String)
このコードは、Ruby の if 文を使用して、変数 value が String クラスのインスタンスであるかどうかを確認しています。具体的には、is_a?
メソッドを使用して、value が String クラスのオブジェクトである場合に true を返し、そうでない場合に false を返します。
is_a?
メソッドは、オブジェクトが特定のクラスまたはそのサブクラスのインスタンスであるかどうかを確認するために使用されます。この場合、value が String クラスのインスタンスである場合に true を返します。
self[key] = value.tr("0-9", "0-9").gsub(/[\s ]+/, "")
Ruby の application_record.rb ファイル内で特定のキーに対応する値を変換して設定するために使用されています。具体的には、全角数字を半角数字に変換し、文字列内のすべての空白(半角スペースおよび全角スペース)を削除しています。
・value の中の全角数字("0" から "9")を対応する半角数字("0" から "9")に変換します。tr
メソッドは、文字列内の特定の文字を他の文字に置換するために使用されます。この場合、全角数字を半角数字に置換しています。
・gsub
メソッドは、文字列内の特定のパターンに一致する部分を置換するために使用されます。/[\s ]+/
は正規表現で、1つ以上の空白文字(半角スペース \s および全角スペース )に一致します。
"" は、置換後の文字列として空文字列を指定しています。これにより、すべての空白文字が削除されます。
※ちなみに、tr
とgsub
は同じような機能に見えるかもしれませんがここでは説明は省きます。それぞれが文字置換と削除に適しているということだけ、認識してもらえれば大丈夫です。
before_validation :normalize_attributes
最後にバリデーションの前に、このメソッドを実行すれば自動修正が完了です。
(例)
birthday = "1990年 3月 1 2日"#ユーザーが左のように入力した場合
p birthday #出力 1990年3月12日
以上、自作アプリ作成の際に役に立ったので記事にしました。