【Ruby on Rails】郵便番号から住所を自動入力

# 目標
![map.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/6928241d-b57f-f2c5-d840-c22000a08a09.gif)

# 開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina

# 前提
※　▶◯◯　を選択すると、説明等が出てきますので、
　　よくわからない場合の参考にしていただければと思います。

homesコントローラーを作成し、以下を記述済。

```rb:config/routes.rb
root 'homes#top'
get 'mypage', to: 'homes#mypage'
```
```rb:app/controllers/homes_controller.rb
class HomesController < ApplicationController
 def top
 end
 def mypage
 end
end
```
# 流れ
1 deviseで住所を入力してログインできるようにする
2 gem 'jp_prefecture'、gem 'jquery-rails'を導入
3 jquery.jpostal.jsを導入
4 application.jsの編集

# １、deviseでのログイン
- [参考](https://qiita.com/japwork/items/8dfb52121036791ac4fb):こちらで詳しく説明しています。

```rb:Gemfile
gem 'devise'
```
```:ターミナル
$ bundle install
$ rails g devise:install
$ rails g devise User
```
下記記述を追加。

```rb:db/migrate/xxxxxxxxxxxxx_devise_create_users.rb
...

<-- ここから-->
      t.integer :postal_code, null: false
      t.string :prefecture_code, null: false
      t.string :city, null: false
      t.string :street, null: false
      t.string :other_address # 番地以降の住所がない場合もあるため、null: falseはつけない
<-- ここまでを追加 -->
      t.timestamps null: false
    end

    add_index :users, :email,                unique: true
    add_index :users, :reset_password_token, unique: true
    # add_index :users, :confirmation_token,   unique: true
    # add_index :users, :unlock_token,         unique: true
  end
end
```
## devise:controller
```:ターミナル
rails g devise:controllers users
```
```rb:app/controllers/users/registrations_controller.rb
# frozen_string_literal: true

class Users::RegistrationsController < Devise::RegistrationsController
  before_action :configure_sign_up_params, only: [:create]
  # before_action :configure_account_update_params, only: [:update]

...

  # protected

  # If you have extra params to permit, append them to the sanitizer.
  def configure_sign_up_params
    devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :postal_code, :prefecture_code, :city, :street, :other_address])
  end

  # If you have extra params to permit, append them to the sanitizer.
  # def configure_account_update_params
  #   devise_parameter_sanitizer.permit(:account_update, keys: [:attribute])
  # end

  # The path used after sign up.
  def after_sign_up_path_for(resource)
    mypage_path
  end

  # The path used after sign up for inactive accounts.
  # def after_inactive_sign_up_path_for(resource)
  #   super(resource)
  # end
end
```
## devise:model
未入力を防ぐため、下記記述を追加。

```rb:app/models/user.rb
  validates :postal_code, presence: true
  validates :prefecture_code, presence: true
  validates :city, presence: true
  validates :street, presence: true
```

## devise:routing
```rb:config/routes.rb
Rails.application.routes.draw do
  devise_for :users, controllers: {
    sessions: 'users/sessions',
    registrations: 'users/registrations',
  }

  root 'homes#top'
  get 'mypage', to: 'homes#mypage'
end
```

## devise:view
```:ターミナル
$ rails g devise:views users
```
form_forの中に記述。

```erb:app/views/devise/registrations/new.html.erb

form_for...

  <div class="field">
    <%= f.label :postal_code %><br>
    <%= f.text_field :postal_code %>
  </div>

  <div class="field">
    <%= f.label :prefecture_code %><br>
    <%= f.collection_select :prefecture_code, JpPrefecture::Prefecture.all, :name, :name %>
  </div>

  <div class="field">
    <%= f.label :city %><br>
    <%= f.text_field :city %>
  </div>

  <div class="field">
    <%= f.label :street %><br>
    <%= f.text_field :street %>
  </div>
  <div class="field">
    <%= f.label :other_address %><br>
    <%= f.text_field :other_address %>
  </div>


...

```
これで住所の入力をする新規登録画面の完成です。

# ２、gemの追加
```rb:Gemfile
gem 'jp_prefecture' # 都道府県コードから都道府県名を変換するgem
gem 'jquery-rails' # RailsでjQueryを使えるようにするgem
```
```:ターミナル
$ bundle install
```

# ３、jquery.jpostal.jsを導入
https://github.com/ninton/jquery.jpostal.js/
上記URLに遷移後、緑色の「Code」タブを押して、
赤丸部分にてzipファイルをダウンロード。
![スクリーンショット 2020-09-11 15.20.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700999/f7a9ac8c-2a8a-8229-18f2-3713bc9ea4a3.png)
解凍後、「jquery.jpostal.js」のファイルを見つけ、
このファイルをapp/assets/javascripts 下に格納。

# ４、application.jsの編集
```js:app/assets/javascripts/application.js
//= require rails-ujs <--削除
//= require jquery <--追加
//= require jquery_ujs <--追加
//= require activestorage
//= require turbolinks
//= require jquery.jpostal <--追加
//= require_tree .

$(function() {
  $(document).on('turbolinks:load', () => {
    $('#user_postal_code').jpostal({
      postcode : [
        '#user_postal_code'
      ],
      address: {
        "#user_prefecture_code": "%3", // # 都道府県が入力される
        "#user_city"           : "%4%5", // # 市区町村と町域が入力される
        "#user_street"         : "%6%7" // # 大口事務所の番地と名称が入力される
      }
    });
  });
});


// # 入力項目フォーマット
// #   %3  都道府県
// #   %4  市区町村
// #   %5  町域
// #   %6  大口事業所の番地 ex)100-6080
// #   %7  大口事業所の名称
```
<details><summary>うまく動作しない時</summary>
おそらくturbolinksの挙動がおかしくなっている可能性が高いため、
link前のlink_toに
data: {"turbolinks"=>false}
を記述することで解決できる場合があります。</details>

下記内容を一番上に追加

```erb:app/views/devise/registrations/new.html.erb
<script type="text/javascript" src="//jpostal-1006.appspot.com/jquery.jpostal.js"></script>
```
# 参考
- [jp_prefecture という都道府県を扱う gem を作った](https://chocoby.jp/blog/2013/02/19/jp-prefecture-gem/)