7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Ruby on Rails】ちょっとしたマスタデータの管理

Last updated at Posted at 2025-03-27

はじめに

Railsアプリケーションの実装で新たにマスタデータを持つ必要が出てきた時に「わざわざテーブルを作りたくない」と思ったことはないでしょうか。
「他テーブルと結合して使うわけでもない」「基本的に更新されない(ほぼ固定値のようなもの)」「データ数も多くない」といった条件が重なってくると、マスタ管理のためだけにテーブルを増やすのは少し抵抗があります。
そんな時に役立ちそうな方法をまとめてみました。

方法1, ActiveModel & クラス内に直接定義

ActiveModel を読み込み、マスタデータもクラス内で全て定義してしまう方法です。ごく一部の機能さえあれば良く、とにかくシンプルに済ませたい時に向いています。

app/models/region.rb
class Region
  include ActiveModel::Model

  attr_accessor :code, :name

  DATA = [
    { code: "R01", name: "北海道地方" },
    { code: "R02", name: "東北地方" },
    { code: "R03", name: "関東地方" },
    { code: "R04", name: "中部地方" },
    { code: "R05", name: "近畿地方" },
    { code: "R06", name: "中国地方" },
    { code: "R07", name: "四国地方" },
    { code: "R08", name: "九州・沖縄地方" }
  ].freeze

  # 区域一覧を取得
  def self.all
    DATA.map { |item| self.new(item) }
  end
end

self.all で定義した通り、区域一覧を取得することができています。

Region.all
=>
[#<Region:0x0000ffff81da9a40 @code="R01", @name="北海道地方">,
 #<Region:0x0000ffff81da9720 @code="R02", @name="東北地方">,
 #<Region:0x0000ffff81da96a8 @code="R03", @name="関東地方">,
 #<Region:0x0000ffff81da9630 @code="R04", @name="中部地方">,
 #<Region:0x0000ffff81da95b8 @code="R05", @name="近畿地方">,
 #<Region:0x0000ffff81da9540 @code="R06", @name="中国地方">,
 #<Region:0x0000ffff81da94c8 @code="R07", @name="四国地方">,
 #<Region:0x0000ffff81da9428 @code="R08", @name="九州・沖縄地方">]

Pros

  • gem も不要かつ1ファイルのみで完結するためとにかくシンプル

Cons

  • マスタデータの量や項目が多いとコードの見通しが悪くなる
  • 必要な処理は自分で書く必要がある

方法2, ActiveModel & YAMLファイル

ActiveModel を使いつつマスタデータをYamlファイルから読み込むように変更したものです。「クラス内でマスタデータを定義するには量や項目が多い」といった場合はこちらの方が良いでしょう。

app/models/region.rb
class Region
  include ActiveModel::Model

  attr_accessor :code, :name

  # yamlからデータをロード
  def self.data
    @data ||= YAML.load_file(Rails.root.join('config', 'master_data', 'regions.yml'))
  end

  # 区域一覧を取得
  def self.all
    data.map { |item| self.new(item) }
  end
end
config/master_data/regions.yml
- code: R01
  name: 北海道地方
- code: R02
  name: 東北地方
- code: R03
  name: 関東地方
- code: R04
  name: 中部地方
- code: R05
  name: 近畿地方
- code: R06
  name: 中国地方
- code: R07
  name: 四国地方
- code: R08
  name: 九州・沖縄地方

Pros

  • データとコードが分離されているため管理しやすい
  • データが増えてもコードの可読性を損なわない

Cons

  • 必要な処理についてはやはり自分で書く必要がある

方法3, ActiveHash & クラス内に直接定義

gem active_hash を利用する方法です。gemをインストールする必要はありますが、1ファイルで完結する上に ActiveRecord と同じ感覚で使うことができます。

導入も簡単。まずはgemをインストールします。

gem 'active_hash'

そして、ActiveHash::Base を継承してクラスを作成します。self.data でマスターデータを定義してください。

app/models/region.rb
class Region < ActiveHash::Base

  self.data = [
    { code: "R01", name: "北海道地方" },
    { code: "R02", name: "東北地方" },
    { code: "R03", name: "関東地方" },
    { code: "R04", name: "中部地方" },
    { code: "R05", name: "近畿地方" },
    { code: "R06", name: "中国地方" },
    { code: "R07", name: "四国地方" },
    { code: "R08", name: "九州・沖縄地方" }
  ]
end

allfind_by 等、ActiveRecord でよく使う処理と同様のことができます。

Region.all
=>
[#<Region:0x0000ffff80b895e0 @attributes={:code=>"R01", :name=>"北海道地方", :id=>1}>,
 #<Region:0x0000ffff80b88bb8 @attributes={:code=>"R02", :name=>"東北地方", :id=>2}>,
 #<Region:0x0000ffff80b88730 @attributes={:code=>"R03", :name=>"関東地方", :id=>3}>,
 #<Region:0x0000ffff80b88348 @attributes={:code=>"R04", :name=>"中部地方", :id=>4}>,
 #<Region:0x0000ffff80b87f60 @attributes={:code=>"R05", :name=>"近畿地方", :id=>5}>,
 #<Region:0x0000ffff80b87b78 @attributes={:code=>"R06", :name=>"中国地方", :id=>6}>,
 #<Region:0x0000ffff80b87790 @attributes={:code=>"R07", :name=>"四国地方", :id=>7}>,
 #<Region:0x0000ffff80b873a8 @attributes={:code=>"R08", :name=>"九州・沖縄地方", :id=>8}>]
 
Region.find_by(code: "R03")
=> #<Region:0x0000ffffa1e48828 @attributes={:code=>"R03", :name=>"関東地方", :id=>3}>

Pros

  • ActiveRecord と同様の感覚で利用することができる
  • 1ファイルで完結するためシンプル

Cons

  • gemへの依存は生まれる
  • マスタデータの量や項目が多いとコードの見通しが悪くなる

方法4, ActiveHash & YAMLファイル

gem active_hash をインストールすると、YAMLファイルをロードして ActiveHash オブジェクトとして扱えるようにする ActiveYaml クラスを使えるようになります。
ActiveYaml::Base を継承してクラスを作成し、set_root_path でマスタデータのYAMLファイルを設置しているディレクトリを、set_filename で読み込むYAMLファイルを指定してください。

app/models/region.rb
class Region < ActiveYaml::Base
  set_root_path Rails.root.join("config", "master_data")
  set_filename "regions"
end

方法3と同様に、ActiveRecord と同じ感覚で操作ができます。

Region.find_by(code: "R02")
=> #<Region:0x0000ffff803b1ea8 @attributes={:code=>"R02", :name=>"東北地方", :id=>2}>

Pros

  • ActiveRecord と同様の感覚で利用することができる
  • データとコードが分離されているため管理しやすい
  • データが増えてもコードの可読性を損なわない

Cons

  • gemへの依存は生まれる

まとめ

マスタデータの量や項目、必要としている機能や実装の手間に応じて適した方法を選択するのが良いでしょう。コードの可読性という観点から、データについてはYAMLファイルで管理した方が感覚的にスッキリはしました。
4つ全てを試した感じでは 「方法4, ActiveHash & YAMLファイル」 がコードの見通しもよく実装の手間も省けて良かったのですが、「どうしてもgemへの依存を避けたい」というような場合は ActiveModel を使って自分で実装するという選択肢も生まれてくるかと思います。

参考

GitHub - active-hash/active_hash
【Rails】ActiveHashでマスターデータを管理する

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?