Railsで都道府県・市区町村のZIPファイルからCSVファイルに変換し、シードにて都道府県・市区町村データをインポートする方法を紹介します。
都道府県・市区町村のマイグレーション作成
まずは、都道府県・市区町村のマイグレーションファイルを作成します。
・db/migrate/20200101000001_create_prefectures.rb
1 2 3 4 5 6 7 8 9 10 11 | class CreatePrefectures < ActiveRecord::Migration[5.2] def change create_table :prefectures, id: :int, unsigned: true, auto_increment: true, options: 'ENGINE=InnoDB COLLATE=utf8_general_ci' do |t| t.string :name, null: false, limit: 4 t.datetime :created_at t.datetime :updated_at t.datetime :deleted_at end end end |
・db/migrate/20200101000002_create_cities.rb
1 2 3 4 5 6 7 8 9 10 11 12 | class CreateCities < ActiveRecord::Migration[5.2] def change create_table :cities, id: :int, unsigned: true, auto_increment: true, options: 'ENGINE=InnoDB COLLATE=utf8_general_ci' do |t| t.integer :prefecture_id t.string :name, null: false, limit: 16 t.datetime :created_at t.datetime :updated_at t.datetime :deleted_at end end end |
都道府県・市区町村のモデル作成
都道府県と市区町村のモデル作成します。1対多のリレーションもはっておきます。
・app/models/prefecture.rb
1 2 3 4 5 6 7 8 | class Prefecture < ApplicationRecord ## # リレーション ## has_many :cities end |
・app/models/city.rb
1 2 3 4 5 6 7 8 | class City < ApplicationRecord ## # リレーション ## belongs_to :prefecture end |
seed.rbで都道府県・市区町村データを取得し、テーブルに保存
seed.rbファイルに都道府県・市区町村データを取得し、テーブルに保存する処理を書いていきます。
今回は日本郵便の都道府県ZIPファイルのダウンロードURLから取得していきます。一度ファイルをダウンロードして、Railsプロジェクトに格納してから、そこを参照して取得しても良いかと思います。
ZIPファイルを一度CSVファイルに変換し、db/配下に保存します。
その後、保存したCSVファイルから都道府県名と市区町村名のカラムを取得し、先ほど作成した都道府県と市区町村のテーブルに挿入していきます。
全取得が完了したら、保存していたCSVファイルを削除して完了です。
・db/seeds.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | require 'csv' require 'zip' PREF_CITY_URL = "http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip" SAVEDIR = "db/" CSVROW_PREFNAME = 6 CSVROW_CITYNAME = 7 save_path = "" # 都道府県・市区町村ZIPを解凍しCSVとして保存 open(URI.escape(PREF_CITY_URL)) do |file| ::Zip::File.open_buffer(file.read) do |zf| zf.each do |entry| savePath = SAVEDIR + entry.name zf.extract(entry, save_path) { true } end end end # 都道府県・市区町村CSVを読み込みテーブルに保存 CSV.foreach(save_path, encoding: "Shift_JIS:UTF-8") do |row| pref_name = row[CSVROW_PREFNAME] city_name = row[CSVROW_CITYNAME] pref = Prefecture.find_or_create_by(:name => pref_name) City.find_or_create_by(:name => city_name, prefecture_id: pref.id) end # 保存したCSVファイルを削除 File.unlink save_path |
以上、都道府県・市区町村データをseedで取得・インポートする方法でした。