Active Hashでプルダウンをオリジナルアプリに実装した


今日は自作のポートフォリオ作りの新規登録画面にプルダウンを追加する実装をしました!
とてもやりたかった機能なのでできた時の嬉しい感情ったらもう。このできたときの感情は、中毒性があります笑
余談はこのあたりで。実装手順を大まかにアウトプットしていきたいと思います。

1, ActiveHash導入

 基本的に変更されないデータがあったとします。基本的に変更されないデータであるため、データベースに保存する必要性はありません。一方、ビューファイルなどにそれらのデータを直接書いてしまうと、可読性に欠けます。
そのようなケースでは、ActiveHashが有用です。

gem 'active_hash'

まずこちらのgemを導入します。(Gemfileの一番下に)
そしてbundle installをします。

2, モデル作成

今回は新規登録画面にプルダウンを実装するのでいつも通りにuserモデルを作成。
ここからもう一つプルダウン用のモデルを別に作ります。今回の私の場合だとスポーツのファン歴についてのプルダウンのためfan_historyモデルを作ります。

% rails g model fan_history --skip-migration

いつもと違うのは「--skip-migration」です。
これは、モデルファイルを作成するときに、マイグレーションファイルの生成を行わないためのオプションです。
今回、記事のファン歴の情報はデータベースに保存しないため、マイグレーションファイルを作成する必要はありません。

3, ActiveHash::Base

ActiveHash::Baseは、ActiveRecordと同様のメソッドが使用できるようになります。
ActiveHash::Baseを継承することで、Genreモデルに定義したオブジェクトに対してActiveRecordのメソッドが使用できるようになります。

fun_history.rb
class FanHistory < ActiveHash::Base
  self.data = [
    { id: 1, name: '--' },
    { id: 2, name: '0~1年' },
    { id: 3, name: '1~5年' },
    { id: 4, name: '5~10年' },
    { id: 5, name: '10年以上' }
  ]
end

こんな感じで記述します。気を付けて欲しい箇所が2点あるので確認してください。
1つめは1行目はデフォルトでActiveHash::Baseになっていないと言う点!
2つめはid:5の行には最後のコンマは記述しない点!
これは私的に気をつけて欲しい箇所です笑 小さなところですがここに気がつけず、少し停滞しました。笑
ちなみにもし都道府県とかをプルダウンにしたいときはとても記述が面倒なので、ネットから頂戴するのがいいと思います。

4, マイグレーションファイルを編集

20201029085540_devise_create_users.rb
      t.string  :nickname,           null: false
      t.string  :email,              null: false, default: ""
      t.string  :encrypted_password, null: false, default: ""
      t.integer :fan_history_id,     null: false  

ここでも気をつける点が2点。
1つめはidをusersテーブルに保存するため_idを追記している点!
2つめはもともとstringだったがintegerに変更している点!
パターンですので理解していれば覚えやすいとおもいます。 db:migrateを忘れずに

5, アソシエーション,バリデーションを設定

user.rb
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to_active_hash :fan_history
  validates :fan_history_id, numericality: { other_than: 1 }

1行目はmustで書くとだけ覚えておきましょう。意味説明は省きます。
2行目で通常のアソシエーションにactive_hashをつけて記述いています。
3行目はもしプルダウンが「--」が選択された状態だと保存できないようにしています。もしfan_history.rbのid1から記述している場合通常のバリデーションだけで問題ないです。

6, 新規登録画面の実装

new.html.erb
<%= f.collection_select(:fan_history_id, FanHistory.all, :id, :name, {}, {class:"fan_history-select"}) %>

ルーティングやコントローラーで繋いできて最後はこの記述を新規登録のビューに記載します。
こちらもパターンなので覚えやすかったです。
形を表すとこんな感じです。

new.html.erb
<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>

まとめ

作業の多さは比較的多いほうだが、流れ的にはとても覚えやすいと感じました。初めての実装だと時間はかかって当然だと思うしエラーも出るかもしれませんが比較的にわかりづらい何時間もつまるようなエラーは出ないと思うのでエラーが出たときはtypoや流れの中でのミスだと思ったほうがいいかもしれないです。
テーブルの数をムダに増やさない為にも、扱うデータが基本的に変更されないものである場合は、ActiveHashを活用していきましょう。