= Ruby on Rails 6 で 郵便番号住所検索 な gem == JpAddressとは 日本郵便の「郵便番号データ(https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip)」を Rails 6.1 で使用するための gem です。 以下の機能を提供します。 * 郵便局提供の郵便番号データをダウンロードして自前DBのテーブル(jp_address_zipcodes)にロードするクラスメソッド。(JpAddress::Zipcode.load_master_data) * 郵便番号を受け取り住所情報をJSONで返却するAPI(jp_address/zipcodes#search)。 要するに、「郵便番号住所検索 ruby gem」でググった人向けの gem です。 お使いのRailsアプリケーションにマウントして使えますので、後必要なのは戻ってくるJSONを加工する手順だけです。 == インストール % gem install jp_address GemFileに追記 gem 'jp_address' テーブルの作成 % bundle exec rails jp_address:install:migrations % bundle exec rails db:migrate == マスターデータのDBへのロード 開発環境 % rails runner -e development 'JpAddress::Zipcode.load_master_data' 本番環境 % rails runner -e production 'JpAddress::Zipcode.load_master_data' 環境にもよりますが、1~3分ぐらいかかると思います。 ※ APP_ROOT/tmp/ を作業ディレクトリに使用しています。 ※ 最初にテーブルをトランケートしますので、毎回「全件insert」になります。 == APIのマウント マウントしたいRailsアプリの config/routes.rb に追記。 mount JpAddress::Engine, at: "/jp_address" == APIの利用 /jp_address にマウントした場合、下記URLへGETリクエストをすることで、JSONを取得できます。 後はこれを好きに加工してテキストボックスなどにセットして使ってください。 get リクエスト先 http://localhost:3000/jp_address/zipcodes/search?zip=5330033 戻り値 JSON {"id":84280,"zip":"5330033","prefecture":"大阪府","city":"大阪市東淀川区","town":"東中島"} == APIを利用するためのサンプル JavaScript フォームには * #zipcode(テキストボックス) * #prefecture_id(セレクトボックス。いわゆる都道府県プルダウン) * #address(テキストボックス) の3要素があり、#zipcodeに入れられた値を元にAPIを叩き、#prefecture_id と #address に 値をセットするサンプルです。 prefecture_id の選択は、都道府県名で行っています。 なので、お使いの都道府県マスターのID値に影響を受けることなく選択できるはずです。 ※ JQuery の存在を前提にしています。 ※ もともと CoffeeScript で書いてあったソースを decaffeinate したものです。 // ここから function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var AddressSearch = function() { "use strict"; function AddressSearch(zip_elem_id, prefecture_elem_id, address_elem_id) { _classCallCheck(this, AddressSearch); this.zip = $(zip_elem_id); this.prefecture = $(prefecture_elem_id); this.address = $(address_elem_id); this.prefecture_elem_id = prefecture_elem_id; } _createClass(AddressSearch, [{ key: "_remove_hyphen", value: function _remove_hyphen() { return this.zip.val(this.zip.val().replace(/-/, '')); } }, { key: "_clear_current_value", value: function _clear_current_value() { $(this.prefecture_elem_id + ' >option:eq(0)').prop('selected', true); return this.address.val(''); } }, { key: "_set_prefecture", value: function _set_prefecture(json) { return $(this.prefecture_elem_id + ' > option').each(function() { if ($(this).text() === json['prefecture']) { return $(this).prop('selected', true); } }); } }, { key: "_set_address", value: function _set_address(json) { return this.address.val(json['city'] + json['town']); } }, { key: "_call_api", value: function _call_api() { var _this = this; return $.getJSON('/jp_address/zipcodes/search', {zip: this.zip.val()}, function(json) { if (json['id'] === null) { return _this._clear_current_value(); } else { _this._set_prefecture(json); return _this._set_address(json); } }); } }, { key: "execute", value: function execute() { this._remove_hyphen(); if (this.zip.val().length === 7) { return this._call_api(); } } }]); return AddressSearch; }(); // ここまでを application.js など共通に読み込まれるファイルに配置。 // ここから // #zipcode, #prefecture_id, #address を各自の環境に合わせて書き換えてください。 $(function() { var address_search = new AddressSearch('#zipcode', '#prefecture_id', '#address'); $('#zipcode').keyup(function() { address_search.execute(); }); }); // ここまでをフォームのあるページに配置。 == 作者 Copyright 2016 (c) Tad Kam, under MIT License. Tad Kam