app/models/jp_address/zipcode.rb in jp_address-1.0.1 vs app/models/jp_address/zipcode.rb in jp_address-1.0.2

- old
+ new

@@ -56,10 +56,76 @@ values ('%s', '%s', '%s', '%s')", row[2], row[6], row[7], _remove_needless_words(row[8]) ] ) ) end + _merge_same_zip_addresses _remove_csv + end + + # 同じ郵便番号を持つレコードを統合します。 + # + # 例:9896712 + # "宮城県","大崎市","鳴子温泉水沼" + # "宮城県","大崎市","鳴子温泉南山" + # "宮城県","大崎市","鳴子温泉山際" + # "宮城県","大崎市","鳴子温泉和田" + # これらは + # "宮城県","大崎市","鳴子温泉" として1つのレコードにします。 + # 共通する地名が抜き出せない場合は空の町名にします。 + def self._merge_same_zip_addresses + group(:zip).having('count(*) > 1').pluck(:zip).each do |dup_zip| + buf = nil + town_names = [] + where(zip: dup_zip).order(:id).each_with_index do |rec, i| + town_names << rec.town if rec.town.present? + if i == 0 + buf = rec.dup + end + rec.destroy + end + shared_town_name = _find_shared_name_from(town_names) + buf.town = shared_town_name + buf.save! + end + nil + end + + # 引数に渡された地名群から、先頭から見て共通となる地名を返します。 + # + # input = %w[鳴子温泉小身川 + # 鳴子温泉川袋 + # 鳴子温泉木戸脇 + # ] + # + # return => 鳴子温泉 + def self._find_shared_name_from(names) + return '' if names.blank? + + name_length_min = names.map{ |n| n.length }.min + diff_pos = nil + chars = [] + + (0..(name_length_min - 1)).each do |pos| + break if diff_pos.present? + char = nil + names.each do |name| + if char.nil? + char = name.each_char.to_a[pos] + chars << char + elsif char != name.each_char.to_a[pos] + diff_pos = pos + break + end + end + end + + if diff_pos.present? && diff_pos > 1 + ret = chars[0, diff_pos].join + return ret + end + + '' end def self._clear_table begin connection.truncate 'jp_address_zipcodes'