Ruby
Rails
seed-fu

seed-fuのseedファイルで特定のディレクトリ以下のCSVを全部読み込む方法

More than 1 year has passed since last update.

まずは、fixturesディレクトリを作ろう

railsで初期データを入れる(seed-fuの使い方)を参考にいざ導入!
書いてある通りにdb/fixturesを作成

モデル

とある大学の講義データです。
毎年、学部、学科ごとにcsvが存在します。
階層でいうと、学科は学部の下に属し、学部は年度の下に属します。
よってディレクトリ構成は、
db/fixtures/2016/学部名/学科名.csv
↑がたくさんあります。

csv読み込み用のseed.rbを作ろう

ということで、実際のコードはこちら

seed.rb
Dir.glob("#{Rails.root}/db/fixtures/2016/*/*.csv").each do |f|
  CSV.read(f).each do |row|
    Lesson.seed do |s|
      s.faculty_id = row[0]
      s.department_id = row[1]
      s.lesson_number = row[2]
      s.lesson_code = row[3]
      s.lesson_name = row[4]
    end    
  end
end

ポイントは「 * 」が使えるということと、「 Dir.glob 」と、「 #{Rails.root} 」くらいですかね。
以外と情報が出てこなかったので、備忘録も兼ねて。

2016/09/28追記・変更

上記のseedプログラムだと主キー(今回はそのままのid)がファイルが変わるたびに0からスタートになって、結果的に登録されるのは最後のCSVファイルだけでした。
そこで、以下のようにグローバル変数$iを宣言して、そこに積み重ねたidをぶちこむという方法で解決!

seed.rb
$i = 1
Dir.glob("#{Rails.root}/db/fixtures/2016/*/*.csv").each do |f|
  CSV.read(f).each.with_index($i) do |row, i|
    Lesson.seed do |s|
      s.id = i
      s.faculty_id = row[0]
      s.department_id = row[1]
      s.lesson_number = row[2]
      s.lesson_code = row[3]
      s.lesson_name = row[4]
      $i = i
    end
  end
end

ポイントは .each.with_index($i)ですかね。

.with_index(数値)で、スタートの数字を決められるとのこと。その(数値)に前のcsvファイルから引き継いだidを入れていく感じです!

後記

そして、メインのCSV読み込みに関してももっと上手な方法がありそうです。ご指摘ください。

ps.初めてのqiita投稿!