RailsでCSVファイルのセルを空白にする方法
はじめに
今回のブログでは、RailsでCSVファイルを生成する際に、連続したデータを空白にする方法について紹介します。
例として、User
モデルのage
カラムを使い、前のユーザーと同じ年齢であればそのセルを空白にするコードを実装していきます。
CSVファイルでは、データが連続している場合、同じ情報を繰り返し表示するのは冗長です。
例えば、年齢が同じユーザーが続く場合は、2回目以降の同じ年齢を省略して表示することで、より見やすく、無駄のないファイルを生成できます。
実装の流れ
まずは、UsersController
にCSV出力用のアクションを作成します。
User
モデルにCSVフォーマットを定義し、CSVファイルを生成して出力します。
# config/routes.rb
Rails.application.routes.draw do
get 'csv_output', to: 'users#csv_output'
end
# app/controllers/users_controller.rb
# Userモデルから全てのユーザーを年齢順に取得し、それをCSV形式で出力
class UsersController < ApplicationController
def csv_output
@users = User.all.order(:age)
send_data(User.csv_format(@users), filename: "ユーザー一覧.csv")
end
end
次に、User
モデルにCSVフォーマットを生成するメソッドを作成します。
作成したコードは下記になります。
# app/models/user.rb
# CSVフォーマットを生成
class User < ApplicationRecord
class << self
def csv_format(users)
CSV.generate do |csv|
csv << ["ID", "性", "名", "年齢", "性別", "給料"]
previous_age = nil
users.each do |user|
csv << format_user_row(user, previous_age)
previous_age = user.age
end
end
end
def format_user_row(user, previous_age)
age = user.age == previous_age ? nil : user.age
[user.id, user.first_name, user.last_name, age, user.sex, user.salary]
end
end
end
上記コードのポイントは下記になります。
まず、csv_format
メソッドは @users で年齢順に取得したUserモデルをusers
という引数で受け取り、CSV.generate
を使ってCSV形式のデータを作成しています。
また、csv <<
を使って、まずヘッダー行(ID、性、名、年齢、性別、給料)を挿入しています。
次に format_user_row
メソッド ですが、こちらのメソッドで各ユーザーごとに行データを作成しています。
previous_age
と現在のuser.age
を比較し、同じ場合には空白(nil
)を挿入します。
今回の Rails で CSV ファイルのセルを空白にする方法の一番のポイントは、条件に応じて値をnil
にするロジックを組み込むことです。
今回の例では、previous_age
という変数を使って前回のユーザーの年齢を保持し、次のユーザーと同じ年齢であればnil
を設定しています。
nil
が CSV ファイル上では空白として扱われるため、特定の条件(同じ年齢が続く)でセルを空白にすることができるのです。
出力例
上記のコードを実行すると、例えば以下のようなCSVが出力されます。
(今回 usersテーブルにはハイキュー!のキャラデータを格納し、csvファイルで出力してみました)
上記のように、連続した年齢が空白になることで、無駄な情報の繰り返しが省略され、見やすいCSVファイルになります。
以上が、RailsでCSVファイルのセルを空白にする方法の説明になります。
まとめ
このテクニックを使うことで、CSVファイルの可読性を向上させることができます。
特定の条件でセルを空白にするのは、特に大量のデータを扱う場面で効果的です。
今回の例では年齢を対象にしましたが、他のデータでも同様の方法が応用可能です。
Discussion