Ruby on Railsでプログラムを書いていると、必ずしもデータベースに保存するほどでもないけれども管理が必要なデータに出会うことがあります。
例えば、ショッピングサイトで扱う洋服のサイズ(S、M、L)や、性別(男性、女性、その他)などです。
この記事では、そんなデータを扱うときに役立つ「ActiveHash」の基本的な働きや使用法を解説します。
さらに、ActiveHashを使う上で気になる「複数選択」データの取り扱いについても深堀りします。
ActiveHashはその簡単さから現場でもよく使われるツールの一つですので、しっかりと理解していきましょう。
ActiveHashとは
ActiveHashとは、ある種の「魔法の箱」のようなものです。
それは、データベースに保存するほどでもないデータを、まるでデータベースに保存されているかのように扱うことができます。
以下の3つの状況で、ActiveHash が活躍します。
- データベースに保存するほど重要でないデータがある時
- データの変化が少ない、または予想される時
- データをActiveRecordのように取り扱いたい時
この ActiveHashを使用すると、データをハッシュ形式で定義し、それをデータベースに格納されているかのように扱うことができます。
なぜデータベースではなくActiveHash?
なぜデータベースではなく、ActiveHashで管理した方が良いのでしょうか?
ここで大切な点は、データベースへの問い合わせ(クエリ)には、それなりの時間とリソースが必要となるということです。
たとえば、あるデータを取得するためにデータベースに問い合わせると、その問い合わせが完了するまでの間、一部のリソースが占有されます。
この問い合わせが頻繁に行われると、その分だけアプリケーション全体のパフォーマンスが低下する可能性があります。
一方、ActiveHashで管理すると、データはアプリケーションのメモリ上に保持されます。
メモリからのデータの取得は、データベースからの取得よりも遥かに高速です。
そのため、頻繁にアクセスするがあまり変更されないようなデータは、ActiveHashで管理するとパフォーマンスの向上に寄与します。
これが、データベースではなくActiveHashを使用する主な理由です。
ですから、例えば定数のようなものや、プログラムの実行中に変更されることがほとんどない設定値など、変更頻度が低くアクセス頻度が高いデータに対してActiveHashを使用することは、一般的に良い実践とされています。
ActiveHashのセッティング
ActiveHashを使い始めるための準備は簡単です。
まずは、宝石箱(Gemfile)に以下の一行を追加し、その後でbundle install
という呪文を唱えます。
gem 'active_hash'
ActiveHashの使い道
さて、ここでActiveHashの使い方を一緒に見ていきましょう。
例えば、ショッピングサイトで扱う洋服のサイズ(S、M、L)を定義するためにActiveHashを使ってみます。
ActiveHashを使用する際には、専用のモデルファイルを手作りします。
class Size < ActiveHash::Base
self.data = [
{id: 1, name: 'S'}, {id: 2, name: 'M'}, {id: 3, name: 'L'}...
end
active_hashでのアソシエーション
さらに、active_hashでは通常のモデル同様にアソシエーションを設定することができます。
例えば、サイズ(Size)モデルと商品(Item)モデルを作り、アソシエーションを組む様子を見てみましょう。
class Size < ActiveHash::Base
include ActiveHash::Associations
has_many :items
...
end
class Item < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to_active_hash :size
end
以上のように、ActiveHashを用いてデータを定義し、そのデータに対してアソシエーションを設定することで、Railsの開発がよりスムーズに進むようになります。
ActiveHashで複数選択を扱う
ActiveHashは複数選択も扱うことが可能です。
たとえば、Userが複数の言語を選択できるケースを考えてみましょう。
まず、言語を定義するLanguageモデルを作成します。
class Language < ActiveHash::Base
self.data = [
{id: 1, name: 'English'},
{id: 2, name: 'Japanese'},
{id: 3, name: 'French'},
// ...
]
end
次に、UserとLanguageの間に中間テーブルUserLanguageを設けます。
class User < ApplicationRecord
has_many :user_languages
has_many :languages, through: :user_languages
end
class UserLanguage < ApplicationRecord
belongs_to :user
belongs_to :language
end
class Language < ApplicationRecord
has_many :user_languages
has_many :users, through: :user_languages
end
これにより、ユーザは複数の言語を選択できるようになります。
ActiveHashを用いれば、定数として扱いたいデータをモデルとして管理し、DBへのアクセスを抑えつつ、複数選択を含む様々なデータ操作を効率的に行うことが可能となります。
まとめ
ActiveHashを使うことで、状態が変わりにくい、あるいは数がそれほど多くないデータをDBに保存せずに済ませることができます。
それにより、アプリケーションのパフォーマンスを向上させることが可能です。
また、複数選択するようなデータ構造を扱う際にもActiveHashを活用できるため、複雑なデータ構造をシンプルに管理することができます。
ActiveHashはRails開発において非常に便利なツールなので、ぜひ積極的に活用してみてください。