#概要
Railsで初期データを作成する場合、seed_fuは便利なのですが、ユーザに初期データ作成を以下のようなseed_fu
の形式で依頼するのは難しいものがあります。
user.rb
# coding: utf-8
User.seed do |s|
s.id = 1
s.name = '山田 花子'
s.email = 'yamada@hogehoge.hoge'
s.groups = Group.where(:name => ['部署1','部署2'])
end
そこで、ユーザにはCSVファイルでデータを作成してもらって、それを読み込むようにしてみます。
基本的な書き方は以下のようになります。
db/fixtures/import.rb
require 'csv'
# インポートファイルを読み込む
def import_read( file_name )
lines = CSV.read("db/fixtures/#{Rails.env}/#{file_name}")
lines.unshift([]) # index 0番目は空行を入れてスキップさせる
lines.each_with_index do |line, idx|
next unless line.length > 0
yield(line, idx) if block_given?
end
end
# CSVファイルの取込
import_read('hoge.csv') do |line, idx|
Hoge.seed do |s|
s.id = idx
s.column1 = line[0]
s.column2 = line[1]
end
end
#サンプル
では、実際にどのように記述していくか、サンプルを掲示します。
テーブル構造などは、こちらを参照してください。
今回、development
環境用に作成していますが、production
、staging
と環境別にフォルダを分けてデータファイルを用意します。
##取り込むCSVファイル
db/fixtures/development/ヘッダ.csv
文房具
自転車
書籍
db/fixtures/development/詳細.csv
文房具,えんぴつ,3
文房具,ボールペン,145
文房具,定規,-5
自転車,ビアンキ,3
自転車,GT,25
db/fixtures/development/部署.csv
総務部,組織の事務を扱う,
秘書課,役員を補佐する,総務部
広報課,情報発信を行う,総務部
人事部,社員情報を管理する,
人事一課,,人事部
人事二課,,人事部
db/fixtures/development/ユーザ.csv
山田 花子,yamada@hogehoge.hoge,秘書課
鈴木 一郎,suzuki@hogehoge.hoge,人事二課,広報課
田中 太郎,tanaka@hogehoge.hoge,人事一課
佐藤 次郎,sato@hogehoge.hoge,人事部,広報課
db/fixtures/development/ゲスト.csv
井上 直太郎,inoue@hogehoge.hoge
大谷 健太郎,ootani@hogehoge.hoge
松本 浩太郎,matsumoto@hogehoge.hoge
##インポート用のRubyファイル
共通メソッド
今回、seed_fuを意識していますが、他でも使えるように、libに共通メソッドとして作成しています。
lib/import.rb
require 'csv'
#
# =データのImportをサポートするメソッド群
#
# Author:: Takaki-K
# Version:: 0.0.1
#
module Import
# == CSVのインポートファイルを読み込む
# 指定されたCSVファイルを読み込み、読み込んだデータを1行単位で配列に格納し、ブロックへ渡す。
# ブロックへは、データ(配列)、Index(1~)を渡す。
#
# === 引数
# - file_path ファイルパス
# - file_name ファイル名称(省略可 デフォルト値=nil)
# - header ヘッダの有無(省略可 デフォルト値=false)
#
def self.csv_read( file_path, file_name=nil, header=false )
file_path = File.expand_path(file_name, file_path) unless file_name.nil?
lines = CSV.read(file_path)
lines.unshift([]) unless header # headerが無い場合は、index 0番目に空行を入れてスキップさせる
lines.each_with_index do |line, idx|
next if idx == 0 # ヘッダ行は読み飛ばす
next unless line.length > 0 # データが無い行は読み飛ばす
yield(line, idx) if block_given?
end
end
end
seed_fu用の読み込みファイル
種類別に読み込みファイルを作成しています。
db/fixtures/data_resources.rb
require "#{Rails.root}/lib/import.rb"
# =データの取込
# データファイルを保存しているフォルダ
data_folder = "#{Rails.root}/db/fixtures/#{Rails.env}"
# ==ヘッダ情報の取込
Import.csv_read(data_folder, 'ヘッダ.csv') do |line, idx|
Header.seed do |s|
s.id = idx
s.title = line[0]
end
end
# ==詳細情報の取込
Import.csv_read(data_folder, '詳細.csv') do |line, idx|
Detail.seed do |s|
s.id = idx
s.header = Header.find_by_title(line[0])
s.name = line[1]
s.stock = line[2]
end
end
db/fixtures/human_resources.rb
require "#{Rails.root}/lib/import.rb"
# =人事情報の取込
# データファイルを保存しているフォルダ
data_folder = "#{Rails.root}/db/fixtures/#{Rails.env}"
# == 部署情報の取込
Import.csv_read(data_folder, '部署.csv') do |line, idx|
Group.seed do |s|
s.id = idx
s.name = line[0]
s.description = line[1]
s.group = Group.find_by_name(line[2])
end
end
# == ユーザ情報の取込
Import.csv_read(data_folder, 'ユーザ.csv') do |line, idx|
User.seed do |s|
s.id = idx
s.name = line[0]
s.email = line[1]
line.shift(2)
s.groups = Group.where(:name => line)
end
end
# == ゲスト情報の取込
Import.csv_read(data_folder, 'ゲスト.csv') do |line, idx|
Guest.seed do |s|
s.id = idx
s.name = line[0]
s.email = line[1]
end
end
#取込
ここまでできれば、取り込むだけです。
bundle exec rake db:seed_fu RAILS_ENV=development