0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails】フィクスチャファイルからCSVファイルを読む込む

Last updated at Posted at 2025-01-20

はじめに

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 %>

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?