はじめに
SmartHRで届出書類機能を開発しているqwyngと申します。
今回はSmartHRの届書書類機能において、日本語エイリアスを用いた開発を行ったので紹介します。
背景
SmartHRの届出書類機能は、書類の作成から電子申請の送信までを一括で行うことができる機能です。
ユーザーは画面上で書類に記入するような感覚で書類の作成を行うことができます。
この体験の実現のために書類のどんな項目にどのような値が入力されたかを永続化する必要があります。 DBのカラム名は英語であるため、開発者は日本語の項目名を英語のカラム名に脳内で変換する必要があります。 この変換が煩わしく、プログラムの修正やレビュー時を含めて開発者の負担になっていました。 そのため、日本語の項目名をそのまま実コードに使えるようにすることを検討しました。
日本語化の是非
日本語の項目名をそのまま使うと「日本語を習熟していない開発者がコードを理解しにくくなる」という問題があります。 しかし、
- 日本語を習熟していない開発者が届出書類機能の開発に関わる可能性は少ない
- すでに既存のコードで
santeikiso
やhokenryou
などのローマ字のネーミングが使われている
以上の理由から、日本語の項目名をコードに使うことにしました。
解決策の候補
DBのカラム名を日本語に変更する
届出書類機能ではPostgresSQLを使用しており、DBのカラム名を日本語に変更することは可能です。
ActiveRecord 7.1.3.2ではカラム名を日本語にしても問題なく動作しそうでした。
しかし、社内で、ライブラリがマルチバイト文字に対応していないゆえに問題が発生するという話を聞いたことがあり、この方法は採用しないことにしました。
ゲッターとセッターの日本語エイリアスを定義する
ゲッターとセッターの日本語エイリアスをそれぞれ定義する方法です。
class Document < ApplicationRecord def 保険料率 insurance_rate end def 保険料率=(value) self.insurance_rate = value end end
単純ですが、影響範囲が小さく、他の部分に影響を与えません。
ですが、ActiveRecord::AttributeMethods::ClassMethods#alias_attribute
というRails側が用意してくれている手段があったのと、単純にコード量が多くなるため、この方法は採用しませんでした。
alias_attributeを使う
最終的に採用した方法です。
行ったことは単純で、ActiveRecord::AttributeMethods::ClassMethods#alias_attribute
を用いて日本語の項目名に対して英語のカラム名をエイリアスとして定義しました。
class Document < ApplicationRecord alias_attribute :保険料率, :insurance_rate end
これによって以下のようなコードが書けるようになりました。
document = Document.create(保険料率: 0.1) document.保険料率 # => 0.1 document.insurance_rate # => 0.1 documents.methods.grep(/保険/) =begin => [:保険料率=, :保険料率_before_type_cast, :保険料率_for_database, :保険料率_came_from_user?, :保険料率?, :保険料率_previously_changed?, :保険料率_changed?, :保険料率_change, :保険料率_will_change!, :保険料率_was, :保険料率_previous_change, :保険料率_previously_was, :restore_保険料率!, :clear_保険料率_change, :saved_change_to_保険料率?, :saved_change_to_保険料率, :保険料率_before_last_save, :will_save_change_to_保険料率?, :保険料率_change_to_be_saved, :保険料率_in_database, :保険料率] =end
効果
この変更によって、開発者は日本語の項目名をそのまま使うことができるようになりました。
例えば複数の項目を使う計算を行う場合、以下のように書くことができます。
def 保険料 = 算定額 * 保険料率
というコードは直感的に理解しやすく、脳内に収まりやすくなりました。
-- def insurance_fee = insurance_base * insurance_rate ++ def 保険料 = 算定額 * 保険料率
テストコードも格段に読みやすくなりました。
context '算定額が100円で保険料率が0.1の場合' do before do document.算定額 = 100 document.保険料率 = 0.1 end it '保険料が算定額の10%になること' do expect(document.保険料).to eq 10 end end
まとめ
日本語の項目名をそのまま使うことで、開発者の負担を減らすことができました。
今回は新規に作成するモデルに対して日本語エイリアスを定義しましたが、既存のモデルにも適用することで、既存のコードの可読性を向上させることができると考えています。
その反面、エイリアスを定義するということは管理すべきインターフェイスが増えるということでもあります。この方法を初めてまだ日が浅いため、今後の運用においても問題が発生しないかを慎重に検討していきたいと考えています。
We Are Hiring!
SmartHR では一緒に SmartHR を作りあげていく仲間を募集中です!
複雑なドメインをプロダクトに落とし込むことに興味がある方をお待ちしています!
少しでも興味を持っていただけたら、カジュアル面談でざっくばらんにお話ししましょう!