【Rails】jpostalとjp_prefectureを用いて住所自動入力の実装

# 目標

**ユーザー新規登録画面で郵便番号を入力すると、それ以降の住所(番地まで)を自動入力する。**
![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579893/fb8341fb-4481-c06f-2d21-59afcd0817ef.gif)

# 開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina

# 前提

下記実装済み。

・[Slim導入](https://qiita.com/matsubishi5/items/b639ffddecc626856039)
・[Bootstrap3導入](https://qiita.com/matsubishi5/items/b117c95f4dd71340cc80)
・[ログイン機能実装](https://qiita.com/matsubishi5/items/5bd8fdd45af955cf137d)

# 実装

### 1.jQueryプラグインを導入

**①下記リンクにアクセスする。**

[jpostal GitHub](https://github.com/ninton/jquery.jpostal.js)

**②`Clone or download`をクリック**
![スクリーンショット 2020-06-09 8.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579893/00077a86-f9fa-def6-503d-d9a187bbce40.png)

**③`Download ZIP`をクリック**
![スクリーンショット 2020-06-09 8.12.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579893/f3d82831-acde-720e-7f76-4e66f75283a3.png)

**④ダウンロードしたフォルダ内の`jquery.jpostal.js`を`app/assets/javascript`に配置する。**
![スクリーンショット 2020-06-09 8.20.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579893/bc072878-645b-1fd5-6f71-f5612369d202.png)

### 2.Gemを導入

```ruby:Gemfile
gem 'jquery-rails'
gem 'jp_prefecture'
```

```terminal:ターミナル
$ bundle
```

```js:application.js
//= require rails-ujs
//= require activestorage
//= require turbolinks 
//= require jquery // turbolinksより下に記述
//= require_tree .
```

### 3.カラムを追加

```terminal:ターミナル
$ rails g migration AddColumnsToUsers postcode:integer prefecture_code:integer address_city:string address_street:string address_building:string
```

```ruby:~_add_columns_to_users.rb
class AddColumnsToUsers < ActiveRecord::Migration[5.2]
  def change
    add_column :users, :postcode, :integer
    add_column :users, :prefecture_code, :integer
    add_column :users, :address_city, :string
    add_column :users, :address_street, :string
    add_column :users, :address_building, :string
  end
end
```

```terminal:ターミナル
$ rails db:migrate
```

### 4.モデルを編集

```ruby:user.rb
include JpPrefecture
jp_prefecture :prefecture_code

def prefecture_name
  JpPrefecture::Prefecture.find(code: prefecture_code).try(:name)
end

def prefecture_name=(prefecture_name)
  self.prefecture_code = JpPrefecture::Prefecture.find(name: prefecture_name).code
end
```

####【解説】
```ruby:
include JpPrefecture
jp_prefecture :prefecture_code
```
➡︎ 都道府県コードから都道府県名に自動で変換する。

```ruby:
def prefecture_name
  JpPrefecture::Prefecture.find(code: prefecture_code).try(:name)
end

def prefecture_name=(prefecture_name)
  self.prefecture_code = JpPrefecture::Prefecture.find(name: prefecture_name).code
end
```
➡︎ `~.prefecture_name`で都道府県名を参照出来る様にする。
例) @user.prefecture_nameで該当ユーザーの住所(都道府県)を表示出来る。

### 5.コントローラーを編集

ストロングパラメーターに住所情報を追加する。

```ruby:application_controller.rb
def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [
    :email,
    :name,
    :postcode,
    :prefecture_name,
    :address_city,
    :address_street,
    :address_building
  ])
end
```

### 6.ビューを編集

```slim:registrations/new.html.slim
/ 追記
= f.label :postcode, '郵便番号'
br
= f.text_field :postcode, autocomplete: 'postcode', class: 'form-control'
br

= f.label :prefecture_name, '都道府県'
br
/ 47都道府県をプルダウンメニューで表示
= f.collection_select :prefecture_code, JpPrefecture::Prefecture.all, :code, :name, { prompt: '選択してください' }, class: 'form-control'
br

= f.label :address_city, '市区町村'
br
= f.text_field :address_city, autocomplete: 'address_city', class: 'form-control'
br

= f.label :address_street, '番地'
br
= f.text_field :address_stree, autocomplete: 'address_street', class: 'form-control'
br

= f.label :address_building, '建物'
br
= f.text_field :address_building, autocomplete: 'address_building', class: 'form-control'
br
```

### 7.JavaScriptファイルを作成・編集

```terminal:ターミナル
$ touch app/assets/javascripts/address_autofill.js
```

```javascript:address_autofill.js
$(function() {
  return $('#user_postcode').jpostal({
    postcode: ['#user_postcode'],
    address: {
      '#user_prefecture_code': '%3',
      '#user_address_city': '%4',
      '#user_address_street': '%5%6%7',
    },
  });
});
```