はじめに
実務で住所を使った処理を実装することがあり、そこで苦労したため、今後同様の対応で苦労しないように記載しました。
苦労したこと
以下のようにお客様の住所の都道府県と市区町村の情報を入力するフォームは元々ありました。そのフォームから入力されたデータを使用したバッチ処理を実装することになりました。すでに作成されたテーブルの中にある都道府県と市区町村を取得したかったのですが、市区町村のデータを取得するのに苦労しました。
なぜなら、市区町村部分は以下のような形式で入っていたため、「さいたま市北区」だけを取得したいという処理が想像以上に難航しました。
さいたま市北区ホゲホゲ1-1-1
最初は正規表現で市区町村部分だけ取得すればよいのでは?と思い、調べていたところ以下の記事を見つけました。
記事の中で市区町村をベタ書きしております。ということは、市区町村名が変わったりしたら、正確に取得できないのでは?と思いました。例えば、埼玉県のさいたま市は元々、浦和市だったのですが、他の市と合併してさいたま市になりました。そのような状況が他の市区町村でも起こった場合、以下のコードを保守し続けなければいけないなと思いました。
(...??[都道府県])((?:旭川|伊達|石狩|盛岡|奥州|田村|南相馬|那須塩原|東村山|武蔵村山|羽村|十日町|上越|富山|野々市|大町|蒲郡|四日市|姫路|大和郡山|廿日市|下松|岩国|田川|大村)市|.+?郡(?:玉村|大町|.+?)[町村]|.+?市.+?区|.+?[市区町村])(.+)
そもそもどれほど市区町村名って変わっているのだろう?と疑問に思い、調べてみたところ意外にも市区町村名って変わってしまっているということを知りました。
また、テストコードを書く際にも労力がかかりそうだと思ったため、別の方法が良いと思いました。
解決法
住所から市区町村を抜き出すためには市区町村のマスター情報が必要と思い、それを含んでるgemはないか探したところ、以下があてはまりました。
- 住所から市区町村を取得してくれるgem
- 郵便番号から市区町村の情報を取得できるgem
個人的には住所から市区町村を抜き出すためのgemを使用したかったのですが、そちらはruby2.6以降が対象で、弊社のrubyは2.5だったため、使用できず、、
gemの選定でrubyのバージョンを早めにチェックすることが大事であることを改めて痛感しました。
仕方なく、郵便番号のお客様情報もテーブルにあったため、そこから市区町村情報を取得して、住所から抜き出すようにしました。
なぜgemで取得した郵便番号から取得した市区町村をそのまま使用しなかったのかを説明します。
そもそも郵便番号というのは一つの郵便番号に紐づいている市区町村は一つと思っていたのですが、そうではなく、一つの郵便番号に複数の市区町村が紐づいていたり、同じ郵便番号なのに、違う都道府県の市区町が紐づいていることがあります。
例えば以下の郵便番号みたいに1つの郵便番号でも違う都道府県の市区町村が紐づいていたりします。(はがきを書く時に郵便番号だけでなく、都道府県や市区町村を書く必要があるのかと思いました!)
郵便番号 498-0000
愛知県 弥富市
三重県 桑名郡木曽岬町
詳しくは以下の記事です。
かなり勉強になりましたが、システム実装するには嬉しくないですね、、
お客様が入力した郵便番号からgemで市区町村を抜き出すことをしました。gemで取得した市区町村の情報とお客様が入力した都道府県、市区町村以降の住所を使って、お客様の市区町村を抜き出すことを致しました。
改善点
今回はバッチ処理で市区町村の情報が必要だったために上記の実装しましたが、お客様が市区町村以降を入力する画面のバリデーションも直したいと思いました。
なぜなら、入力フォームが手入力であり、ユーザが間違えた市区町村を入力してしまうことがあるため、チェックする仕組みを実装したいと思いました。
今回の学び
- データを結合することは簡単だが、分割するのは難しい。また、工数もかなりかかる。住所の市区町村とそれ以降で分けた入力フォームとテーブル設計にすることが大事。以下のようなフォームはgood。
以下のようなフォームはBad。
- gemが対応しているrubyバージョンのチェックは大切。なるべく早めにgemを使ってみて、要件に合うかもチェックする。