はじめに
MinitestのフィクスチャファイルからCSV形式で書かれたデータを読み込むソースコードを読解した記録です。
- フィクスチャ
- 事前に定義したデータをテスト実行直前にtestデータベースに導入できる
- ひとつのモデルにつき一つのフィクスチャファイルが作成され、test/fixtures/ディレクトリの下に置かれる
- YAML形式で記述される
- CSV
- 「Comma Seperated Value」の略
- 値や項目をカンマ(,)で区切って書いたデータ形式
- 互換性と汎用性が高い
環境
- Rails6.1.7
- Ruby2.7.8
testディレクトリの構造
test/
(省略)
├─ fixtures
│ └─ hoge.yml
│ └─ fuga.yml
└─ └─ piyo.yml
├─ data
│ └─ hoge.csv
│ └─ fuga.csv
└─ └─ piyo.csv
- fixruresディレクトリ
- yaml形式のファイルを配置する
- ファイル名が対応するdataディレクトリのCSVデータを読み込む
- dataディレクトリ
- CSV形式のデータが書かれたファイルを配置する
test/data/hoge.csv
id,name,price,size
1,foo,100,M
2,bar,500,L
3,baz,200,S
ソースコード例
test/fixtures/hoge.yml
<% require 'csv' %>
<% CSV.foreach("test/data/#{File.basename(__FILE__).split('.').first}.csv", headers: true) do |row| %>
# __FILE__: test/fixtures/hoge.yml
# File.basename(__FILE__): hoge.yml
# "test/data/#{File.basename(__FILE__).split('.').first}.csv": "test/data/hoge.csv"
# CSV.foreach("test/data/#{File.basename(__FILE__).split('.').first}.csv", headers: true) do |row| ~ end : test/data/hoge.csvの各行をブロック変数rowに渡す、一行目はヘッダとして扱う
# 下記でYaml形式に整形する
<%= row['id'] %>:
<% row.headers.each do |column| %>
<%= column %>: <%= row[column] %>
<% end %>
<% end %>
読解①
<% require 'csv' %>
<% CSV.foreach("test/data/#{File.basename(__FILE__).split('.').first}.csv", headers: true) do |row| %>
# <%= row['id'] %>:
# <% row.headers.each do |column| %>
# <%= column %>: <%= row[column] %>
# <% end %>
<% end %>
-
require 'csv'
- CSVライブラリを読む込む
-
CSV.foreach(path, options = Hash.new) do |row| ~ end
-
CSVファイルのパスを指定し、各行を読み込んでブロック変数rowに渡す
-
オプションには
CSV.new
と同じオプションを指定できる -
headers: :first_row
もしくはheaders: true
をオプションに指定するとCSV ファイルの一行目をヘッダとして扱う
-
-
__FILE__
- 擬似変数
- 現在のソースファイル名
- フルパスとは限らないため、フルパスが必要な場合は
File.expand_path(__FILE__)
とする必要がある - 実行している「ファイル名のみ」を取得する場合は
File.basename(__FILE__)
で取得する
読解②
#<% require 'csv' %>
#<% CSV.foreach("test/data/#{File.basename(__FILE__).split('.').first}.csv", headers: true) do |row| %>
<%= row['id'] %>:
<% row.headers.each do |column| %>
<%= column %>: <%= row[column] %>
<% end %>
#<% end %>
-
row['id']
- idの値を取得する
irb(main):014:1* CSV.foreach("hoge.csv", headers: true) do |row|
irb(main):015:1* puts row['id']
irb(main):016:0> end
1
2
3
-
row.headers
- ヘッダにあたるキーを取得する
irb(main):002:1* CSV.foreach("hoge.csv", headers: true) do |row|
irb(main):003:1* puts row.headers
irb(main):004:0> end
id
name
price
size
id
name
price
size
id
name
price
size
- 下記のように、yaml形式で出力される
irb(main):020:1* CSV.foreach("test.csv", headers: true) do |row|
irb(main):021:1* puts "#{row['id']}:"
irb(main):022:2* row.headers.each do |column|
irb(main):023:2* puts "#{column}: #{row[column]}"
irb(main):024:1* end
irb(main):025:0> end
1:
id: 1
name: foo
price: 100
size: M
2:
id: 2
name: bar
price: 500
size: L
3:
id: 3
name: baz
price: 200
size: S
おわりに
サンプルデータを大量に作成したい場合には下記のようなERBのコードも活用できます。データのタイプによって使い分けたいと思います。
<% 1000.times do |n| %>
user_<%= n %>:
username: <%= "user#{n}" %>
email: <%= "user#{n}@example.com" %>
<% end %>