Ruby 自作ブログ開発記

Railsでマスターデータ(seeds)をcsv管理する

このWordPressを廃止して自作ブログに置き換えようと絶賛開発中でして、カテゴリデータなどをcsvで管理して db:seed したいなと思い、実装したのでメモ。

注意ポイント

若干荒い実装ですが、ちょっとした個人開発なら十分な機能だと思います。

 

要件

やりたいことは

  • データはcsvファイルで管理して初期データ投入したい
  • seed実行する対象のテーブル指定をしたい

実行イメージはこんな感じ。

$ bin/rails db:seed TABLES=name1,name2,name3

 

実装

db/seeds 以下に テーブル名.csv というファイル名でヘッダー付きのcsvファイルを置きます。

db/seeds/
├── article_categories.csv
├── articles.csv
├── categories.csv
└── category_trees.csv

CSVファイルの中身はこんな感じ。

例. categories.csv

id,name,slug
1,"フリーランスエンジニア","freelance-engineer"
2,"キャリア","career"
3,"制度・手続き","office-procedure"
4,"データベース・SQL","database"
5,"Go言語","golang"
6,"老後・資産形成","money"
7,"税金・確定申告","tax"
8,"案件・エージェント","orders"
9,"Udemy","udemy"
10,"プログラミング学習","programming-learning"
11,"副業・複業","side-jobs"
12,"働き方・生活","workstyle-life"
13,"禁煙","%e7%a6%81%e7%85%99"
14,"応用情報技術者試験","ipa-ap"
15,"引越","moving"
16,"Ruby","ruby"
17,"便利サービス・商品","awsome-goods"
18,"書籍","books"
19,"子育て","childcare"
20,"基本情報技術者試験","ipa-fe"
21,"英語学習","english"

 

db/seed.rbではdb/seeds/*.csvを読み込んでActiveRecordのupsret_all でデータ投入するようにします。

require "csv"

# 実行方法: bin/rails db:seed TABLES=t1,t2,t3
# TABLESで指定したテーブルのみupsert
# 未指定の場合はdb/seeds/以下のcsvすべてが多少
pattern = ENV["TABLES"].blank? ? "db/seeds/*.csv" : "db/seeds/{#{ENV["TABLES"]}}.csv"

Dir.glob(Rails.root.join(pattern)).each do |path|
  filename = File.basename(path, ".csv")
  klass = Module.const_get(filename.classify)
  data = CSV.read(path, headers: true).map(&:to_h)
  klass.insert_all(data) if data.present?
  puts "DONE. file: #{filename}, class: #{klass}"
end

コメントに書いた通り、TABLES=categories,tagsといったように指定があればそのファイルのみを、無ければ全ファイルを対象にします。

実行

TABLES指定なし。

rails db:seed TABLES指定なし

TABLES指定あり

bin/rails db:seed TABLS指定あり

 

補足

今回はマスターデータの量が多くない+初期データ投入が目的なので十分かなと思っています。

大きなプロジェクトだと次のような考慮が必要になってくるでしょう。

-Ruby, 自作ブログ開発記