active_hashを用いて都道府県データを表示してみた

##なぜactive_hashを使うのか？

<strong>都道府県のデータなど、変更される可能性が低いものをハッシュとして管理できるため、わざわざテーブルを作成する必要が無い</strong>

というメリットがあります。

今回の内容はフリマアプリでactive_hashを利用した際に、つまずいた点があったので、
備忘録としてまとめたものです。


##環境

Rails 5.2.3
Ruby 2.5.1


##導入方法

gem active_hashをインストール

```
gem 'active_hash'
```
bundle installを実行。 

<img width="568" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/c5ecda79-c744-138a-575c-925d760cafc7.png">

active_hashのインストールが完了しましたので

続いてモデルの作成に移ります。

##モデルを作成

まずはaddress.rbを作成します。

```
rails g model adderss
```
作成したアドレス内に以下の内容のように編集する

```
class Address < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
end
```

この記述により、後ほど作成するprefecture.rbとアソシエーションを組むことができ、prefecture.rbの内容を利用することができます。

rails db:migrateを行った後、prefecture.rbを作成します。

内容は以下のように編集しましょう

```
class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end
```

これで、モデル内の準備は完了です。

次はコントローラー内を編集します。


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

今回はフリマアプリなので、products_controller.rb内のnewアクション内に記述を行います。

```
def
  @address = Prefecture.all
end
```
これにより＠addressでprefectureを利用できるようになりました。

rails cでも確認してみると

<img width="598" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/979b8b79-ea94-2dc7-f98b-5e016f016759.png">

下は見切れてしまっていますが、取り出せているようです。

続いてviewファイル内のformの記述を編集し、ユーザーが都道府県を選択できるようにします。

##viewファイル内を編集、都道府県データが表示されるか確認

```
= form_for @product do |f|
```
の記述から、= f.text_field,  = f.text_areaといった形で入力フォームを作成しているので

```
f.collection_select :prefecture_id, Prefecture.all, :id, :name
```
フォームを設置したい箇所に上記を記述し、投稿してみる。

<img width="1440" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/db494d74-499b-f188-da54-661c69fd28bb.png">
エラーが出てしまった....

binding.pryを用いて、prefectureが取り出せているか確認してみることに
<img width="626" alt="5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/f54730f4-42ad-844c-e131-0eeae2506350.png">


<img width="552" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/d5304a0b-55cf-ab8b-2827-9a680f650f6d.png">

しっかり取り出せている...

formの記述に誤りがあるのかもしれないとのことで、以下に変更

```
 = f.select :prefecture_id, Prefecture.all, :id, :name
```


<img width="1440" alt="6 .png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/25a61c4c-40c8-9f64-259c-4889368a1575.png">

またしても、エラー...

form以外に怪しい点は無いか探してみると

<strong>なんとproductテーブル内にprefectureの入力を反映させるprefecture_idが存在していなかった。</strong>

これでは、中身があっても入れ物が無いようなもので、エラーが起きてしまうのも無理はない

no method errorは文字通りmethodが定義されていないというエラーでもあれば、<strong>もっと単純にコンピュータ側から「これがなんだかわからない」というメッセージ</strong>でもあったことを知る。

カラムを追加して確認すると、、、
<img width="594" alt="7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594063/814faf48-fa38-fafb-758d-59170b8b5265.png">


無事、実装完了。

##終わりに

初めてactive_hash実装にあたって苦労する箇所は多かったが、使いこなすメリットは大きいと感じました。

ただエラー内容は単純なものだったこともあり、もう少し早く解決できた内容だったかなと...

まだまだ初学者の粋を脱することは難しいようだ