Class: Basho::City

Inherits:
Data
  • Object
show all
Defined in:
lib/basho/city.rb

Overview

市区町村を表すイミュータブルなデータクラス。

DBバックエンドが有効な場合、クラスメソッドは自動的に DB::City 経由で検索する。

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil) ⇒ City

Returns a new instance of City.



27
28
29
# File 'lib/basho/city.rb', line 27

def initialize(district: nil, capital: false, deprecated_at: nil, successor_code: nil, **)
  super
end

Instance Attribute Details

#capitalObject (readonly)

Returns the value of attribute capital

Returns:

  • (Object)

    the current value of capital



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

#codeObject (readonly)

Returns the value of attribute code

Returns:

  • (Object)

    the current value of code



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

Returns the value of attribute deprecated_at

Returns:

  • (Object)

    the current value of deprecated_at



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

#districtObject (readonly)

Returns the value of attribute district

Returns:

  • (Object)

    the current value of district



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

#nameObject (readonly)

Returns the value of attribute name

Returns:

  • (Object)

    the current value of name



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

Returns the value of attribute name_kana

Returns:

  • (Object)

    the current value of name_kana



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

Returns the value of attribute prefecture_code

Returns:

  • (Object)

    the current value of prefecture_code



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

#successor_codeObject (readonly)

Returns the value of attribute successor_code

Returns:

  • (Object)

    the current value of successor_code



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

Class Method Details

.find(code) ⇒ City, ...

6桁自治体コードで市区町村を検索する。

Parameters:

  • code (String)

    6桁自治体コード(例: "131016")

Returns:



92
93
94
95
96
97
98
99
# File 'lib/basho/city.rb', line 92

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

.valid_code?(code) ⇒ Boolean

JIS X 0401 チェックディジットで自治体コードを検証する。

Parameters:

  • code (String)

    6桁自治体コード

Returns:

  • (Boolean)


115
116
117
# File 'lib/basho/city.rb', line 115

def valid_code?(code)
  CodeValidator.valid?(code)
end

.where(prefecture_code:) ⇒ Array<City>, Array<DB::City>

都道府県コードで市区町村を絞り込む。

Parameters:

  • prefecture_code (Integer)

    都道府県コード

Returns:



105
106
107
108
109
# File 'lib/basho/city.rb', line 105

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

Instance Method Details

#active?Boolean

現行(未廃止)かどうかを返す。

Returns:

  • (Boolean)


51
# File 'lib/basho/city.rb', line 51

def active? = deprecated_at.nil?

#capital?Boolean

県庁所在地かどうかを返す。

Returns:

  • (Boolean)


34
# File 'lib/basho/city.rb', line 34

def capital? = capital

#currentCity

合併チェーンをたどり、現行の市区町村を返す。 アクティブ市区町村は即座に自身を返す。ループ検出・深度制限付き。

Returns:



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/basho/city.rb', line 64

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

#deprecated?Boolean

廃止済みかどうかを返す。

Returns:

  • (Boolean)


46
# File 'lib/basho/city.rb', line 46

def deprecated? = !deprecated_at.nil?

#full_nameString

郡名付きの正式名を返す。郡がない場合は #name と同じ。

Returns:

  • (String)

    例: "島尻郡八重瀬町"



39
40
41
# File 'lib/basho/city.rb', line 39

def full_name
  district ? "#{district}#{name}" : name
end

#prefecturePrefecture, DB::Prefecture

所属する都道府県を返す。



83
84
85
# File 'lib/basho/city.rb', line 83

def prefecture
  Prefecture.find(prefecture_code)
end

#successorCity?

合併先の市区町村を返す。

Returns:



56
57
58
# File 'lib/basho/city.rb', line 56

def successor
  City.find(successor_code) if successor_code
end