🙃

RailsでCSVファイルのセルを空白にする方法

2024/09/15に公開

はじめに

今回のブログでは、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