Railsでは、seedコマンドでDBにデータを投入することができます。
通常はdb/seeds.rbに投入したいデータを記述しますが、可読性が低くなってしまいます。
そこで投入するデータをCSVファイルに記述することで、データの中身も確認しやすく便利になりますので紹介します。
ディレクトリー構成
今回ディレクトリー構成は、以下のような構成とします。
dbディレクトリー構成配下にseeds.rbを作成して、テーブル名.csvのファイルを作成します。
例えばPrefectureモデルのデータを投入したい場合、prefectures.csvファイルを作成します。
app
├ models
├ <モデル>
db
├ seeds.eb
├ seeds
├ <CSVファイル>
CSVファイル
CSVファイルにはヘッダーを記述して、モデルの属性とマッピングさせます。
id,code,name,name_kana
1,01,北海道,ホッカイドウ
2,02,青森県,アオモリケン
3,03,岩手県,イワテケン
CSVを読み込んでDBに投入する処理を記述
db/seeds.rbにCSVを読み込んで、DBに投入する処理を記述します。
model_namesの変数に、seed対象のモデルを記述します。
モデル名をテーブル名に変換して、CSVファイルのデータを1件ずつ検索を行います。
そしてデータがあれば更新、データがない場合は新規で保存します。
require 'csv'
model_names = %w(Prefecutre)
model_names.each do |model_name|
model = model_name.constantize
table_name = model.table_name
CSV.read("#{Rails.root}/db/seeds/#{table_name}.csv", headers: true).map(&:to_h).each do |model_params|
if model.exists?(id: model_params["id"])
record = model.find(model_params["id"])
record.update(model_params.dup.delete_if {|_,v| v.blank?})
else
record = model.new(model_params.dup.delete_if {|_,v| v.blank?})
record.save
if Rails.configuration.database_configuration[Rails.env]["adapter"] != "sqlite3"
ActiveRecord::Base.connection.execute("select setval('#{table_name}_id_seq',(select max(id) from #{table_name}))")
end
end
end
end
まとめ
初期データをseedファイルに記述すると、データの可読性が下がり辛くなることがよくあります。
CSVファイルにデータの中身を記述することで、データを追加するのも簡単にできますので参考にしてみてください。