Help us understand the problem. What is going on with this article?

Rubyだけでできる、静的なマスタデータをテーブルなしで持つ方法

More than 1 year has passed since last update.

テーマ

静的なマスタデータをテーブルやGemを使わずRubyで作ってみる

とりあえずGemを使えばいい? 本当に必要そうなGemのみ使うようにしてRubyでできることは自前でやってみようよ。
マスタデータをサクッと持ちたい場合、テーブル作ったり、Gem active_hashを使わなくてもできるよ。

サンプルを作ってみる

東京都の市区町村データを使ったサンプルアプリのデータを使いながら実践していきます。

物件検索サービスなどでよく使われている東京都のエリア(都心部、23区東部、23区西部等)のデータをサンプルにしてみる。
(全てのデータを作るのは大変だったので、都心部、23区東部のみ作成してます。)

app/models下にclassファイルを作成し、ActiveRecordでおなじみのメソッドはもちろん使えないので、自分で定義する。
今回はall, find系を定義

app/models/tokyo_area.rb
class  TokyoArea
  class << self
  def all
    [
      {id: 1, name: '都心部', cities:[{id: 13101, name: "千代田区"}, {id: 13102, name: "中央区"}, {id: 13103, name: "港区"}, {id: 13104, name: "新宿区"}, {id: 13105, name: "文京区"}, {id: 13113, name: "渋谷区"}]},
      {id: 2, name: '23区東部', cities:[{id: 13106, name: "台東区"}, {id: 13107, name: "墨田区"}, {id: 13108, name: "江東区"}, {id: 13118, name: "荒川区"}, {id: 13121, name: "足立区"}, {id: 13122, name: "葛飾区"}, {id: 13123, name: "江戸川区"}]}
    ]
  end

  def find(id)
    self.all.find{ |item| item[:id] == id.to_i }
  end

  def find_by_name(name)
    self.all.find{ |item| item[:name] == name }
  end

  def find_by_id(id)
    self.find(id)
  end
  end
end

rails consoleで試してみる

pry(main)> TokyoArea.all
=> [{:id=>1, :name=>"都心部", :cities=>[{:id=>13101, :name=>"千代田区"}, {:id=>13102, :name=>"中央区"}, {:id=>13103, :name=>"港区"}, {:id=>13104, :name=>"新宿区"}, {:id=>13105, :name=>"文京区"}, {:id=>13113, :name=>"渋谷区"}]},
 {:id=>2, :name=>"23区東部", :cities=>[{:id=>13106, :name=>"台東区"}, {:id=>13107, :name=>"墨田区"}, {:id=>13108, :name=>"江東区"}, {:id=>13118, :name=>"荒川区"}, {:id=>13121, :name=>"足立区"}, {:id=>13122, :name=>"葛飾区"}, {:id=>13123, :name=>"江戸川区"}]}]

pry(main)> TokyoArea.find(1)
=> {:id=>1, :name=>"都心部", :cities=>[{:id=>13101, :name=>"千代田区"}, {:id=>13102, :name=>"中央区"}, {:id=>13103, :name=>"港区"}, {:id=>13104, :name=>"新宿区"}, {:id=>13105, :name=>"文京区"}, {:id=>13113, :name=>"渋谷区"}]}

pry(main)> TokyoArea.find(1)[:cities]
=> [{:id=>13101, :name=>"千代田区"}, {:id=>13102, :name=>"中央区"}, {:id=>13103, :name=>"港区"}, {:id=>13104, :name=>"新宿区"}, {:id=>13105, :name=>"文京区"}, {:id=>13113, :name=>"渋谷区"}]

pry(main)> TokyoArea.find(1)[:cities].map { |item| item[:id] }
=> [13101, 13102, 13103, 13104, 13105, 13113]

おー、あたかもデータベースから取得しているかのようにかけました!
もちろん、定義した通り、取得した結果は配列とハッシュで返ってくるところが違いますね。

まとめ

今までRailsだけでなく、Rubyが使えるとRails側でなんとなくいい感じにやってくれてあまり考えなかった実装の裏側がクリアになり構造を理解できるようになる気がします!
今まではGemを深く考えることなく使っていたのですが、Gemの先々のサポート体制など自分ではコントロールできない問題もあるので、その際の選択肢としても自分でできることは自作するという観点も持っておこうと思います╭( ・ㅂ・)و

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした