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バックエンドに切り替わる。

Examples:

ActiveRecordモデルでの利用

class Shop < ApplicationRecord
  include Basho
  basho :city_code
  basho_postal :postal_code, prefecture: :pref_name, city: :city_name
end

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バージョン.

Returns:

  • (String)

    現在のgemバージョン

"0.5.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Attribute Details

#capitalBoolean (readonly)

Returns 県庁所在地フラグ.

Returns:

  • (Boolean)

    県庁所在地フラグ



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_codeString (readonly)

Returns 県庁所在地の6桁自治体コード(例: "131041").

Returns:

  • (String)

    県庁所在地の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, **options)
      attrs = code.nil? ? options : { 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_nameString (readonly)

Returns 市区町村名(例: "世田谷区").

Returns:

  • (String)

    市区町村名(例: "世田谷区")



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

#codeString (readonly)

Returns 7桁郵便番号(ハイフンなし、例: "1540011").

Returns:

  • (String)

    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_atString? (readonly)

Returns 廃止日(例: "2025-04-01")。現行自治体は +nil+.

Returns:

  • (String, nil)

    廃止日(例: "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

#districtString? (readonly)

Returns 郡名(例: "島尻郡")。郡に属する町村のみ設定.

Returns:

  • (String, 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

#nameString (readonly)

Returns 都道府県名(例: "東京都").

Returns:

  • (String)

    都道府県名(例: "東京都")



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_enString (readonly)

Returns 英語名(例: "Tokyo").

Returns:

  • (String)

    英語名(例: "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_hiraganaString (readonly)

Returns ひらがな名(例: "とうきょうと").

Returns:

  • (String)

    ひらがな名(例: "とうきょうと")



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, **options)
      attrs = code.nil? ? options : { 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_kanaString (readonly)

Returns カタカナ名(例: "トウキョウト").

Returns:

  • (String)

    カタカナ名(例: "トウキョウト")



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_codeInteger (readonly)

Returns 都道府県コード(1〜47).

Returns:

  • (Integer)

    都道府県コード(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_codesArray<Integer> (readonly)

Returns 所属する都道府県コードの配列.

Returns:

  • (Array<Integer>)

    所属する都道府県コードの配列



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_nameString (readonly)

Returns 地方名(例: "関東").

Returns:

  • (String)

    地方名(例: "関東")



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, **options)
      attrs = code.nil? ? options : { 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_codeString? (readonly)

Returns 合併先の6桁自治体コード。合併先がない場合は +nil+.

Returns:

  • (String, nil)

    合併先の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

#townString (readonly)

Returns 町域名(例: "上馬").

Returns:

  • (String)

    町域名(例: "上馬")



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

#typeString (readonly)

Returns 種別("都" / "道" / "府" / "県").

Returns:

  • (String)

    種別("都" / "道" / "府" / "県")



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, **options)
      attrs = code.nil? ? options : { 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.

バックエンドを強制指定する。主にテスト用。

Parameters:

  • value (Boolean)

    +true+ でDBバックエンド、+false+ でメモリバックエンド



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+ テーブルが存在するかを検出する。 結果はプロセスの生存期間中キャッシュされる。スレッドセーフ。

Returns:

  • (Boolean)

    DBバックエンドが利用可能なら +true+



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