Ruby on Rails 〜ActiveHashをまとめてみました〜

都道府県名一覧やカテゴリーなど基本的に変更されないデータは データベースに保存せずに、ActiveHashというGemを使います。

準備

Gemfileに

gem 'active_hash'

と記述して、「bundle install」を実行します。

つづいて、ターミナルで

% rails g model game

を実行して、テーブルを作成します。

定義と継承

app/modelsディレクトリにgenre.rbファイルを作成します。

そしてこのファイルに定義します。

class Genre < ActiveHash::Base
 self.data = [
   { id: 1, name: '--' },
   { id: 2, name: 'RPG' },
   { id: 3, name: '格闘' },
   { id: 4, name: 'レース' },
   { id: 5, name: 'シュミレーション' },
   { id: 6, name: 'リズム' },
   { id: 7, name: 'アクション' },
   { id: 8, name: 'スポーツ' },
   { id: 9, name: 'ストラテジー' },
   { id: 10, name: 'その他' }
 ]
 end

「ActiveHash::Base」と記述して継承することで、 ジャンルのデータが使用できるようになります。

class CreateArticles < ActiveRecord::Migration[6.0]
 def change
   create_table :game do |t|
     t.string     :title        , null: false
     t.text       :text         , null: false
     t.integer    :genre_id     , null: false
     t.timestamps
   end
 end
end

テーブルにGenreモデルを外部キーとすることで紐付いたデータを扱えるようになります。 記述ができたら、「rails db:migrate」を実行します。

アソシエーション

紐付いたデータを習得できるように、gameモデルとGenreモデル間でアソシエーションを設定するために「module(モジュール)」を使います。

moduleは簡単にいうと、メソッドをまとめているものです。

アソシエーションを設定します。

ActiveHashを用いて、モデルをアソシエーションの設定をするためにはmoduleを取り込む必要があります。

belongs_toの場合

gameモデルは1つのジャンルに紐づくので「belongs_to」を設定します。

belongs_toの場合は 「extend ActiveHash::Associations::ActiveRecordExtensions」 と記述します。

class Article < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre
end

has_manyの場合

Genreモデルは、複数のゲームに紐づくので「has_many」を設定します。 has_manyの場合は 「include ActiveHash::Associations」 と記述します。

class Genre < ActiveHash::Base
 self.data = [
   { id: 1, name: '--' },
   { id: 2, name: 'RPG' },
   { id: 3, name: '格闘' },
   { id: 4, name: 'レース' },
   { id: 5, name: 'シュミレーション' },
   { id: 6, name: 'リズム' },
   { id: 7, name: 'アクション' },
   { id: 8, name: 'スポーツ' },
   { id: 9, name: 'ストラテジー' },
   { id: 10, name: 'その他' }
 ]

  include ActiveHash::Associations
  has_many :articles

 end

これで、アソシエーションの設定は完了です。

バリデーション

バリデーションを設定します。

空のジャンルが選択できないようにします。

class game < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :genre

  #空のtitleとtextを保存できないようにする
  validates :title, :text, presence: true

  #ジャンルの選択が「--」の時は保存できないようにする
  validates :genre_id, numericality: { other_than: 1 } 
end

numericalityは、数値かどうかを検証するバリデーションです。 「ーー」では保存できないようにしたいので、numericality: { other_than: 1 }とすることで、id:1以外であれば保存できるという意味になっています。

作成したジャンルをプルダウンで表示させるには

<%= f.collection_select(:genre_id, Genre.all, :id, :name, {}, {class:"genre-select"}) %>
<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>

と記述します。

以上がActiveHashの流れとなります。