Module: Basho
- Defined in:
- lib/basho.rb,
lib/basho/db.rb,
lib/basho/city.rb,
lib/basho/engine.rb,
lib/basho/region.rb,
lib/basho/db/city.rb,
lib/basho/version.rb,
lib/basho/prefecture.rb,
lib/basho/data/loader.rb,
lib/basho/postal_code.rb,
lib/basho/db/prefecture.rb,
lib/basho/code_validator.rb,
lib/basho/active_record/base.rb,
lib/basho/active_record/postal_auto_resolve.rb,
lib/generators/basho/install_tables/install_tables_generator.rb,
lib/generators/basho/upgrade_deprecation/upgrade_deprecation_generator.rb
Overview
日本の住所データ(都道府県・市区町村・郵便番号・地方区分)を統一的に扱うgem。
デフォルトでは同梱のJSONファイルからデータを読み込む。 +basho_prefectures+ / +basho_cities+ テーブルが存在すれば自動的にDBバックエンドに切り替わる。
Defined Under Namespace
Modules: ActiveRecord, CodeValidator, DB, Data, Generators Classes: City, Engine, Error, PostalCode, Prefecture, Region
Constant Summary collapse
- MAX_SUCCESSOR_DEPTH =
10- VERSION =
Returns 現在のgemバージョン.
"0.5.0"
Instance Attribute Summary collapse
-
#capital ⇒ Boolean
readonly
県庁所在地フラグ.
-
#capital_code ⇒ String
readonly
県庁所在地の6桁自治体コード(例: "131041").
-
#city_name ⇒ String
readonly
市区町村名(例: "世田谷区").
-
#code ⇒ String
readonly
7桁郵便番号(ハイフンなし、例: "1540011").
-
#deprecated_at ⇒ String?
readonly
廃止日(例: "2025-04-01")。現行自治体は +nil+.
-
#district ⇒ String?
readonly
郡名(例: "島尻郡")。郡に属する町村のみ設定.
-
#name ⇒ String
readonly
都道府県名(例: "東京都").
-
#name_en ⇒ String
readonly
英語名(例: "Tokyo").
-
#name_hiragana ⇒ String
readonly
ひらがな名(例: "とうきょうと").
-
#name_kana ⇒ String
readonly
カタカナ名(例: "トウキョウト").
-
#prefecture_code ⇒ Integer
readonly
都道府県コード(1〜47).
-
#prefecture_codes ⇒ Array<Integer>
readonly
所属する都道府県コードの配列.
-
#region_name ⇒ String
readonly
地方名(例: "関東").
-
#successor_code ⇒ String?
readonly
合併先の6桁自治体コード。合併先がない場合は +nil+.
-
#town ⇒ String
readonly
町域名(例: "上馬").
-
#type ⇒ String
readonly
種別("都" / "道" / "府" / "県").
Class Method Summary collapse
-
.db=(value) ⇒ void
バックエンドを強制指定する。主にテスト用。.
-
.db? ⇒ Boolean
+basho_prefectures+ テーブルが存在するかを検出する。 結果はプロセスの生存期間中キャッシュされる。スレッドセーフ。.
- .included(base) ⇒ Object
-
.reset_db_cache! ⇒ void
DB検出キャッシュをリセットする。テスト時やマイグレーション後の再検出に使用。.
Instance Attribute Details
#capital ⇒ Boolean (readonly)
Returns 県庁所在地フラグ.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#capital_code ⇒ String (readonly)
Returns 県庁所在地の6桁自治体コード(例: "131041").
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/basho/prefecture.rb', line 24 Prefecture = ::Data.define(:code, :name, :name_en, :name_kana, :name_hiragana, :region_name, :type, :capital_code) do # 所属する地方を返す。 # # @return [Region] def region Region.find(region_name) end # 所属する市区町村の一覧を返す。 # # @return [Array<City>, Array<DB::City>] def cities City.where(prefecture_code: code) end # 県庁所在地を返す。 # # @return [City, DB::City, nil] def capital City.find(capital_code) end class << self # 全47都道府県を返す。 # # @return [Array<Prefecture>, Array<DB::Prefecture>] def all return DB::Prefecture.all.to_a if Basho.db? @all ||= Data::Loader.prefectures.map { |data| new(**data) }.freeze end # 都道府県を検索する。 # # @overload find(code) # @param code [Integer] 都道府県コード # @overload find(name:) # @param name [String] 日本語名(例: "東京都") # @overload find(name_en:) # @param name_en [String] 英語名(例: "Tokyo") # @return [Prefecture, DB::Prefecture, nil] def find(code = nil, **) attrs = code.nil? ? : { code: code } return if attrs.empty? key, value = attrs.first return DB::Prefecture.find_by(key => value) if Basho.db? all.find { |pref| pref.public_send(key) == value } end # 都道府県を地方名で絞り込む。引数なしで全件返す。 # # @param region [String, nil] 地方名(例: "関東") # @return [Array<Prefecture>, Array<DB::Prefecture>] def where(region: nil) return all unless region return DB::Prefecture.where(region_name: region).to_a if Basho.db? all.select { |pref| pref.region_name == region } end # メモリキャッシュをクリアする。 # # @return [void] # @api private def reset_cache! remove_instance_variable(:@all) if defined?(@all) end end end |
#city_name ⇒ String (readonly)
Returns 市区町村名(例: "世田谷区").
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/basho/postal_code.rb', line 15 PostalCode = ::Data.define(:code, :prefecture_code, :city_name, :town) do # ハイフン付きの郵便番号を返す。 # # @return [String] 例: "154-0011" def formatted_code "#{code[0..2]}-#{code[3..]}" end # 都道府県名を返す。 # # @return [String, nil] 例: "東京都" def prefecture_name prefecture&.name end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture, nil] def prefecture Prefecture.find(prefecture_code) end class << self # 郵便番号で検索する。ハイフン有無どちらも可。 # # @param code [String] 郵便番号(例: "154-0011", "1540011") # @return [PostalCode, nil] def find(code) where(code: code).first end # 郵便番号で検索し、配列で返す。共有郵便番号の場合は複数件。 # # @param code [String] 郵便番号 # @return [Array<PostalCode>] def where(code:) normalized = code.to_s.delete("-") return [] unless normalized.match?(/\A\d{7}\z/) prefix = normalized[0..2] Data::Loader.postal_codes(prefix) .filter_map { |data| new(**data) if data[:code] == normalized } end end end |
#code ⇒ String (readonly)
Returns 7桁郵便番号(ハイフンなし、例: "1540011").
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#deprecated_at ⇒ String? (readonly)
Returns 廃止日(例: "2025-04-01")。現行自治体は +nil+.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#district ⇒ String? (readonly)
Returns 郡名(例: "島尻郡")。郡に属する町村のみ設定.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#name ⇒ String (readonly)
Returns 都道府県名(例: "東京都").
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#name_en ⇒ String (readonly)
Returns 英語名(例: "Tokyo").
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/basho/region.rb', line 13 Region = ::Data.define(:name, :name_en, :prefecture_codes) do # 所属する都道府県の一覧を返す。 # # @return [Array<Prefecture>] def prefectures prefecture_codes.map { |code| Prefecture.find(code) } end class << self # 全9地方を返す。 # # @return [Array<Region>] def all @all ||= [ new(name: "北海道", name_en: "Hokkaido", prefecture_codes: [1]), new(name: "東北", name_en: "Tohoku", prefecture_codes: [2, 3, 4, 5, 6, 7]), new(name: "関東", name_en: "Kanto", prefecture_codes: [8, 9, 10, 11, 12, 13, 14]), new(name: "中部", name_en: "Chubu", prefecture_codes: [15, 16, 17, 18, 19, 20, 21, 22, 23]), new(name: "近畿", name_en: "Kinki", prefecture_codes: [24, 25, 26, 27, 28, 29, 30]), new(name: "中国", name_en: "Chugoku", prefecture_codes: [31, 32, 33, 34, 35]), new(name: "四国", name_en: "Shikoku", prefecture_codes: [36, 37, 38, 39]), new(name: "九州", name_en: "Kyushu", prefecture_codes: [40, 41, 42, 43, 44, 45, 46]), new(name: "沖縄", name_en: "Okinawa", prefecture_codes: [47]) ].freeze end # 日本語名または英語名で地方を検索する。 # # @param name [String] 地方名(例: "関東", "Kanto") # @return [Region, nil] def find(name) all.find { |region| region.name == name || region.name_en == name } end end end |
#name_hiragana ⇒ String (readonly)
Returns ひらがな名(例: "とうきょうと").
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/basho/prefecture.rb', line 24 Prefecture = ::Data.define(:code, :name, :name_en, :name_kana, :name_hiragana, :region_name, :type, :capital_code) do # 所属する地方を返す。 # # @return [Region] def region Region.find(region_name) end # 所属する市区町村の一覧を返す。 # # @return [Array<City>, Array<DB::City>] def cities City.where(prefecture_code: code) end # 県庁所在地を返す。 # # @return [City, DB::City, nil] def capital City.find(capital_code) end class << self # 全47都道府県を返す。 # # @return [Array<Prefecture>, Array<DB::Prefecture>] def all return DB::Prefecture.all.to_a if Basho.db? @all ||= Data::Loader.prefectures.map { |data| new(**data) }.freeze end # 都道府県を検索する。 # # @overload find(code) # @param code [Integer] 都道府県コード # @overload find(name:) # @param name [String] 日本語名(例: "東京都") # @overload find(name_en:) # @param name_en [String] 英語名(例: "Tokyo") # @return [Prefecture, DB::Prefecture, nil] def find(code = nil, **) attrs = code.nil? ? : { code: code } return if attrs.empty? key, value = attrs.first return DB::Prefecture.find_by(key => value) if Basho.db? all.find { |pref| pref.public_send(key) == value } end # 都道府県を地方名で絞り込む。引数なしで全件返す。 # # @param region [String, nil] 地方名(例: "関東") # @return [Array<Prefecture>, Array<DB::Prefecture>] def where(region: nil) return all unless region return DB::Prefecture.where(region_name: region).to_a if Basho.db? all.select { |pref| pref.region_name == region } end # メモリキャッシュをクリアする。 # # @return [void] # @api private def reset_cache! remove_instance_variable(:@all) if defined?(@all) end end end |
#name_kana ⇒ String (readonly)
Returns カタカナ名(例: "トウキョウト").
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#prefecture_code ⇒ Integer (readonly)
Returns 都道府県コード(1〜47).
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#prefecture_codes ⇒ Array<Integer> (readonly)
Returns 所属する都道府県コードの配列.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/basho/region.rb', line 13 Region = ::Data.define(:name, :name_en, :prefecture_codes) do # 所属する都道府県の一覧を返す。 # # @return [Array<Prefecture>] def prefectures prefecture_codes.map { |code| Prefecture.find(code) } end class << self # 全9地方を返す。 # # @return [Array<Region>] def all @all ||= [ new(name: "北海道", name_en: "Hokkaido", prefecture_codes: [1]), new(name: "東北", name_en: "Tohoku", prefecture_codes: [2, 3, 4, 5, 6, 7]), new(name: "関東", name_en: "Kanto", prefecture_codes: [8, 9, 10, 11, 12, 13, 14]), new(name: "中部", name_en: "Chubu", prefecture_codes: [15, 16, 17, 18, 19, 20, 21, 22, 23]), new(name: "近畿", name_en: "Kinki", prefecture_codes: [24, 25, 26, 27, 28, 29, 30]), new(name: "中国", name_en: "Chugoku", prefecture_codes: [31, 32, 33, 34, 35]), new(name: "四国", name_en: "Shikoku", prefecture_codes: [36, 37, 38, 39]), new(name: "九州", name_en: "Kyushu", prefecture_codes: [40, 41, 42, 43, 44, 45, 46]), new(name: "沖縄", name_en: "Okinawa", prefecture_codes: [47]) ].freeze end # 日本語名または英語名で地方を検索する。 # # @param name [String] 地方名(例: "関東", "Kanto") # @return [Region, nil] def find(name) all.find { |region| region.name == name || region.name_en == name } end end end |
#region_name ⇒ String (readonly)
Returns 地方名(例: "関東").
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/basho/prefecture.rb', line 24 Prefecture = ::Data.define(:code, :name, :name_en, :name_kana, :name_hiragana, :region_name, :type, :capital_code) do # 所属する地方を返す。 # # @return [Region] def region Region.find(region_name) end # 所属する市区町村の一覧を返す。 # # @return [Array<City>, Array<DB::City>] def cities City.where(prefecture_code: code) end # 県庁所在地を返す。 # # @return [City, DB::City, nil] def capital City.find(capital_code) end class << self # 全47都道府県を返す。 # # @return [Array<Prefecture>, Array<DB::Prefecture>] def all return DB::Prefecture.all.to_a if Basho.db? @all ||= Data::Loader.prefectures.map { |data| new(**data) }.freeze end # 都道府県を検索する。 # # @overload find(code) # @param code [Integer] 都道府県コード # @overload find(name:) # @param name [String] 日本語名(例: "東京都") # @overload find(name_en:) # @param name_en [String] 英語名(例: "Tokyo") # @return [Prefecture, DB::Prefecture, nil] def find(code = nil, **) attrs = code.nil? ? : { code: code } return if attrs.empty? key, value = attrs.first return DB::Prefecture.find_by(key => value) if Basho.db? all.find { |pref| pref.public_send(key) == value } end # 都道府県を地方名で絞り込む。引数なしで全件返す。 # # @param region [String, nil] 地方名(例: "関東") # @return [Array<Prefecture>, Array<DB::Prefecture>] def where(region: nil) return all unless region return DB::Prefecture.where(region_name: region).to_a if Basho.db? all.select { |pref| pref.region_name == region } end # メモリキャッシュをクリアする。 # # @return [void] # @api private def reset_cache! remove_instance_variable(:@all) if defined?(@all) end end end |
#successor_code ⇒ String? (readonly)
Returns 合併先の6桁自治体コード。合併先がない場合は +nil+.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/basho/city.rb', line 25 City = ::Data.define(:code, :prefecture_code, :name, :name_kana, :district, :capital, :deprecated_at, :successor_code) do def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **) super end # 県庁所在地かどうかを返す。 # # @return [Boolean] def capital? = capital # 郡名付きの正式名を返す。郡がない場合は {#name} と同じ。 # # @return [String] 例: "島尻郡八重瀬町" def full_name district ? "#{district}#{name}" : name end # 廃止済みかどうかを返す。 # # @return [Boolean] def deprecated? = !deprecated_at.nil? # 現行(未廃止)かどうかを返す。 # # @return [Boolean] def active? = deprecated_at.nil? # 合併先の市区町村を返す。 # # @return [City, nil] def successor City.find(successor_code) if successor_code end # 合併チェーンをたどり、現行の市区町村を返す。 # アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。 # # @return [City] def current return self unless successor_code city = self seen = Set.new while city.successor_code && seen.add?(city.successor_code) break if seen.size > MAX_SUCCESSOR_DEPTH next_city = City.find(city.successor_code) break unless next_city city = next_city end city end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture] def prefecture Prefecture.find(prefecture_code) end class << self # 6桁自治体コードで市区町村を検索する。 # # @param code [String] 6桁自治体コード(例: "131016") # @return [City, DB::City, nil] def find(code) return nil unless code.is_a?(String) && code.size == 6 return DB::City.find_by(code: code) if Basho.db? pref_code = code[0..1].to_i where(prefecture_code: pref_code).find { |city| city.code == code } || find_deprecated(code) end # 都道府県コードで市区町村を絞り込む。 # # @param prefecture_code [Integer] 都道府県コード # @return [Array<City>, Array<DB::City>] def where(prefecture_code:) return DB::City.where(prefecture_code: prefecture_code).to_a if Basho.db? Data::Loader.cities(prefecture_code).map { |data| new(**data) } end # JIS X 0401 チェックディジットで自治体コードを検証する。 # # @param code [String] 6桁自治体コード # @return [Boolean] def valid_code?(code) CodeValidator.valid?(code) end private def find_deprecated(code) Data::Loader.deprecated_city(code)&.then { |data| new(**data) } end end end |
#town ⇒ String (readonly)
Returns 町域名(例: "上馬").
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/basho/postal_code.rb', line 15 PostalCode = ::Data.define(:code, :prefecture_code, :city_name, :town) do # ハイフン付きの郵便番号を返す。 # # @return [String] 例: "154-0011" def formatted_code "#{code[0..2]}-#{code[3..]}" end # 都道府県名を返す。 # # @return [String, nil] 例: "東京都" def prefecture_name prefecture&.name end # 所属する都道府県を返す。 # # @return [Prefecture, DB::Prefecture, nil] def prefecture Prefecture.find(prefecture_code) end class << self # 郵便番号で検索する。ハイフン有無どちらも可。 # # @param code [String] 郵便番号(例: "154-0011", "1540011") # @return [PostalCode, nil] def find(code) where(code: code).first end # 郵便番号で検索し、配列で返す。共有郵便番号の場合は複数件。 # # @param code [String] 郵便番号 # @return [Array<PostalCode>] def where(code:) normalized = code.to_s.delete("-") return [] unless normalized.match?(/\A\d{7}\z/) prefix = normalized[0..2] Data::Loader.postal_codes(prefix) .filter_map { |data| new(**data) if data[:code] == normalized } end end end |
#type ⇒ String (readonly)
Returns 種別("都" / "道" / "府" / "県").
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/basho/prefecture.rb', line 24 Prefecture = ::Data.define(:code, :name, :name_en, :name_kana, :name_hiragana, :region_name, :type, :capital_code) do # 所属する地方を返す。 # # @return [Region] def region Region.find(region_name) end # 所属する市区町村の一覧を返す。 # # @return [Array<City>, Array<DB::City>] def cities City.where(prefecture_code: code) end # 県庁所在地を返す。 # # @return [City, DB::City, nil] def capital City.find(capital_code) end class << self # 全47都道府県を返す。 # # @return [Array<Prefecture>, Array<DB::Prefecture>] def all return DB::Prefecture.all.to_a if Basho.db? @all ||= Data::Loader.prefectures.map { |data| new(**data) }.freeze end # 都道府県を検索する。 # # @overload find(code) # @param code [Integer] 都道府県コード # @overload find(name:) # @param name [String] 日本語名(例: "東京都") # @overload find(name_en:) # @param name_en [String] 英語名(例: "Tokyo") # @return [Prefecture, DB::Prefecture, nil] def find(code = nil, **) attrs = code.nil? ? : { code: code } return if attrs.empty? key, value = attrs.first return DB::Prefecture.find_by(key => value) if Basho.db? all.find { |pref| pref.public_send(key) == value } end # 都道府県を地方名で絞り込む。引数なしで全件返す。 # # @param region [String, nil] 地方名(例: "関東") # @return [Array<Prefecture>, Array<DB::Prefecture>] def where(region: nil) return all unless region return DB::Prefecture.where(region_name: region).to_a if Basho.db? all.select { |pref| pref.region_name == region } end # メモリキャッシュをクリアする。 # # @return [void] # @api private def reset_cache! remove_instance_variable(:@all) if defined?(@all) end end end |
Class Method Details
.db=(value) ⇒ void
This method returns an undefined value.
バックエンドを強制指定する。主にテスト用。
61 62 63 64 |
# File 'lib/basho.rb', line 61 def self.db=(value) @db = value require "basho/db" if value end |
.db? ⇒ Boolean
+basho_prefectures+ テーブルが存在するかを検出する。 結果はプロセスの生存期間中キャッシュされる。スレッドセーフ。
34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/basho.rb', line 34 def self.db? return @db if defined?(@db) @db_mutex.synchronize do return @db if defined?(@db) @db = defined?(::ActiveRecord::Base) && ::ActiveRecord::Base.connection.table_exists?("basho_prefectures") require "basho/db" if @db @db end rescue ::ActiveRecord::ConnectionNotEstablished, ::ActiveRecord::NoDatabaseError @db = false end |
.included(base) ⇒ Object
67 68 69 |
# File 'lib/basho.rb', line 67 def self.included(base) base.extend ActiveRecord::Base end |
.reset_db_cache! ⇒ void
This method returns an undefined value.
DB検出キャッシュをリセットする。テスト時やマイグレーション後の再検出に使用。
52 53 54 55 |
# File 'lib/basho.rb', line 52 def self.reset_db_cache! remove_instance_variable(:@db) if defined?(@db) Prefecture.reset_cache! if Prefecture.respond_to?(:reset_cache!) end |