ActiveHashの導入〜使用まで

Railsの勉強をしていてActiveHashというGemを使うことがあったので備忘録として残しておきます。


・ActiveHashとは
・ActiveHashの導入
・ActiveHashの使い方（長いですが手順に沿っていけば使えます）

この３つについて触れておきます。まだプログラミング初心者なので深くは語れないです。


<h1>ActiveHashとは</h1>
Active_Hashとは、変更されないデータをモデルファイル内に直接記述することで、データベースへ保存せずに<strong>読み取り専用</strong>のデータを取り扱うことができるGemのことです。



<h4>分かりやすく言うと、、、</h4>
基本的に変更されないデータ（静的データ）、「都道府県」や「市区町村」などのデータを擬似モデルにハッシュ形式で格納して、呼び出して使う事ができる便利なや〜つです。

何が便利かって言うとテーブルを作らなくて済む事です！！！！
データの中身が変わらないときは基本的にActiveHashを使いましょう！
最初は難しく感じますがすぐに慣れます！

<h1>ActiveHashの導入</h1>
まずGemfileに以下の一文を記述します

```ruby:Gemfile
gem 'active_hash'
```
記述したらターミナルでbundle installをしましょう！

```terminal:ターミナル
% bundle install
```
このbundle installと言うコマンドはGemfileに書かれたgemを一斉にインストールしてくれるコマンドです、新しくGemを追加したら必ず実行しましょう！

これでActiveHashの挿入は終わりです
<h3>ドチャクソ簡単ですね♪</h3>



<h1>ActiveHashの使い方</h1>

まず前提条件として今回は「都道府県(prefecture)」を作成しそれを「商品（items）」のテーブルに保存する手順で紹介していきます。
※なお「商品（items）」のテーブルは作成済みとします。
作成していない場合はrails g model itemsで作成してください

以下の手順で進めていきます。

①都道府県のデータを格納するためのモデルを作成
②データの格納
③アソシエーションを定義
④itemsのマイグレーションファイルに取得する外部キーを記述


## ①都道府県のデータを格納するためのモデルを作成
作成したいディレクトリ内で以下のコマンドをターミナルで実行しましょう！

```terminal:ターミナル
% rails g model prefecture --skip-migration

```
①の解説

rails g model prefectureでprefecture(都道府県)のモデルを作成します、その時のオプションで<strong>--skip-migration</strong>と言うオプションを使用します、このオプションは<strong>マイグレーションファイルを作成しないでくださいね、</strong>と言うオプションになります。
マイグレーションファイルとはdbディレクトリの中のmigrateディレクトリの中のファオルのことを指します。
これ→「db/migrate/2020.......」

ActiveHashではこのマイグレーションファイルは必要ないので
<strong>--skip-migration</strong>を使用しました。

```terminal:ターミナル
% rails g model prefecture --skip-migration　
Running via Spring preloader in process 26071
      invoke  active_record
      create    app/models/prefecture.rb
      invoke    rspec
      create      spec/models/prefecture_spec.rb
      invoke      factory_bot
      create        spec/factories/prefectures.rb

```
これらのファイルが生成されれば成功です。
もし間違えてオプションを付けずに「rails <font color="red">g</font> model prefecture」のコマンドで作成したら
「rails <font color="red">d</font> model prefecture」を実行して、作成したprefectureモデルを削除してからもう一度「rails g model prefecture --skip-migration」を実行しましょう！

<h1>②データの格納</h1>

先ほど作成した「app/models/prefecture.rb」のファイルに以下を記述します。

```ruby:app/models/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
```
 

この時、モデル作成時にデフォルトで以下の記述がありますがそれの上から貼り付けましょう、いらないので。

```ruby:app/models/prefecture.rb
class Prefecture < ApplicationRecord
end
```

②の解説

・まず元々書かれていた「class Prefecture < ApplicationRecord」
は「ApplicationRecord」と言うクラスを継承してくださいと言う記述になるので消しました（ActiveHash::Baseと言うクラスを継承してほしいため）。

・ActiveHashの基本的な格納方法は以下になります

```ruby:activehashの格納方法

class モデルクラス名 < ActiveHash::Base
  self.data = [
      {カラム名: 値, カラム名: 値}, {カラム名: 値, カラム名: 値}
  ]
end

```
なので
<strong>id</strong>と<strong>name</strong>が<strong>カラム名</strong>
<strong>整数</strong>と<strong>都道府県</strong>が<strong>値</strong>となります。


<h1>③アソシエーションを定義</h1>
今回は「一つの商品は一つの都道府県を持っている」と言う形を取りたいので
「Item belongs to Prefecture」になります。
item.rbに以下の記述しましょう！

```ruby:models/item.rb
 extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :prefecture
```

③の解説



・この時prefecture側は
「一つの都道府県はいくつもアイテムを持っている」
「Prefecture has many Items」になりますがprefecture側にはアソシエーションは記述する必要はありません。ActiveHashを使用した時は、いい感じに解釈してくれるので記載しなくていいです！

<h1>④itemsのマイグレーションファイルに取得する外部キーを記述</h1>

itemのマイグレーションファイルにprefectureの外部キーを取得するためのカラムを追加しましょう！
カラムを追加したらマイグレーションを実行しましょう！マイグレーションファイルを実行していたら「rails db:rollback」で停止しましょう！
またrailsサーバーを起動していたら「controll + C」でサーバーを停止し
「rails s」でサーバーも起動し直しましょう！

```ruby:db/migrate/2020....create_items.rb
class CreateItems < ActiveRecord::Migration[6.0]
  def change
    create_table :items do |t|  
      #↓この1行を追加↓
      t.integer    :prefecture_id, null: false
      #↑この1行を追加↑
      foreign_key: true
      t.timestamps
    end
  end
end
```
```terminal:ターミナル
% rails db:rollback 
   ↑マイグレーションファイルの停止コマンド

% rails db:migrate
  ↑マイグレーションファイルの実行コマンド

controll + C　を実行後以下を実行

% rails s
  ↑railsサーバーの起動コマンド
```

④の解説

・外部キーを取得するのですがreferensesの型を使わずにinteger型を使用しています、これには理由があり,,,
<h3>そもそも今回はprefectureのテーブルを作成していないのでreferences型は使えないのです！</h3>
references型とinteger型の違いについてはそれぞれで調べてください。

・ 再起動のコマンドあれこれ、テーブルを変更したときは必ず実行する必要があるので注意してください。railsに怒られます。


<h1>⑤使用する時の記述方法</h1>

使用したいファイルに以下を記述します
今回はitemsのファイルに使用したいのでitems/index.html.erbに記述していきます。

```erb:items/index.html.erb
<%= f.collection_select(:prefecture_id, Prefecture.all, :id, :name, {include_blank: "---"}, {class:"クラス名", id:"id名"}) %>
```
⑤の解説

まず以下をご覧ください

```
<%= form.collection_select(①保存されるカラム名, ②オブジェクトの配列, ③カラムに保存される項目, ④選択肢に表示されるカラム名, ⑤{オプション}, ⑥{htmlオプション} ) %>
```

一つずつ解説していきます
・<strong><%=form.collection_select%></strong>はrailsに用意されているヘルパーメソッドになります。これはプルダウン式の表示を表します。

・①の保存されるカラム名はprefectureのidを保存したいので<strong>prefecture_id</strong>になります

・②のオブジェクトの配列は「②データの格納」でPrefectureに格納したデータのどのデータを取り出すかを指定しています「.all」と言うクラスメソッドを使用していますが他にも色々ありますが調べてください。

・③のカラムに保存される項目は「:id」にしましょう！「:name」でも大丈夫です！

・④選択肢に表示されるカラム名はパッと見で分かりやすくするために「:name」を指定しましょう

・⑤{オプション}ここのオプションは今回<strong>{include_blank: "---"}</strong>を使用しました、これは何も入力されていなければ「---」を表示することを指します。

・⑥{htmlオプション}これはHTMLのクラス名やid名を記述するところです、今回は使い方だけなので省いて書きました、必要な方はクラス名やid名を記述してください。

以上がActiveHashの使い方までの説明になります!



<h1>まとめ</h1>
ActiveHashとは読み取り専用のデータを扱うためのGemのこと
導入方法は「gem 'active_hash'」を記述してから「bundle install」する
使い方は頑張る


最後までありがとうございました！


参考記事
https://pikawaka.com/rails/active_hash

https://github.com/zilkey/active_hash