LoginSignup
3
2

More than 1 year has passed since last update.

【Rails】csvファイルをインポート→整形してDBに保存する

Last updated at Posted at 2022-06-02

やりたいこと

csvファイルをアップロードして、必要なデータを抽出し、DBに保存
データが重複している際は既存データにアップロードしたデータを上書きする

前提条件

rails7系
DB作成済み

実装手順

① gemを追加

gem 'roo'

Gemfileにcsvを読み込むためのgemを追加し、bundle installする。

② ルーティングの設定

config/routes.rb
get    'data_upload'          => 'data_upload#index'
post   'data_upload'          => 'data_upload#create'

③ 標準ライブラリを追加

config/application.rb
require 'csv'

④ viewにアップロード用のformを作成

Rails5.1より導入されたform_withを使ってアップロード用のフォームを作成します。
指定したpathに対してpostリクエストを投げます。

app/views/data_upload/index.html.erb
<%= form_with url: data_upload_path do |f| %>
  <%= f.file_field(:upload_file) %>
  <%= submit_tag "インポートする" %>
<% end %>

⑤ controllerにactionを追加

app/controllers/data_upload_controller.rb
class DataUploadController < ApplicationController

  # get => data_upload
  def index
    upload_file = params[:upload_file]
  end
  
  # post => data_upload
  def create
    if params[:upload_file].present?
      upload_file = params[:upload_file].tempfile

      # ファイルの内容によってはEncodingErrorが出ますので適宜調整してください
      CSV.foreach(upload_file.path, headers: true, encoding: 'cp932') do |row|

        # recruiting_idがあった場合はレコードを呼び出す、ない場合は新しく作成
        recruiting = Recruiting.find_by(recruiting_id: row["求人ID"]) || Recruiting.new
        recruiting.attributes = convert_csv_to_hash(row)
        recruiting.save
      end
      redirect_to root_path
    end
  end

  private

  # csvの欲しいデータがある列とDBのカラムを指定してデータを入れます。
  def convert_csv_to_hash(row)
    params = {
      recruiting_id: row['求人ID'],
      title: row['求人名(募集職種)'],
      salary: row['給与'],
      office_hours: row['勤務時間'],
      skills: row['必須スキル'],
      place: row['勤務地']
    }
    return params
  end
end

参考文献

3
2
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
3
2