【Vue.js + Rails】CSVファイルをimportし、DBに登録

【Vue.js + Rails】CSVファイルをimportし、DBに登録

はじめに

Vue.js + RailsCSVファイルやTSVファイルをimport→DB登録する機会がありましたので、実装内容のメモです。

Vue.jsではVuetifyを使用してコードを書いてます。

Gemfileに追加

gem 'roo'

Excel形式のファイル等を扱えるgem 'roo'を使用。

bundle installを忘れずに。

routes.rbに追加

 namespace :api, {format: 'json'} do
  namespace :v1 do
   resources :orders do
    post :import,on: :collection
   end
  end
 end

Vue.js

 <template>
   <div class="register_field">
   <h3>在庫管理</h3>
    <div class="input-container">
    <v-file-input v-on:change="selected_order_file"
     chips counter show-size truncate-length="50"></v-file-input>
    <v-btn v-on:click="order_file_import()" depressed color="primary">登録</v-btn>
    </div>
   </div>
 </template>
 <script>
 import Vue from 'vue'
 import VueRouter from 'vue-router'
 import axios from 'axios';

 export default{
   data:function(){
   return{
     register_order_file: null
    }
   },
   methods:{
   selected_order_file(e){
     this.register_order_file = e
   },
   order_file_import(){
   let order_file_import_api = "/api/v1/orders/import"
   let formData = new FormData();
    formData.append('file', this.register_shipment_file);

    axios.post(order_file_import_api,formData).then(response => (
     console.log(response)
    )).catch(error =>(
     alert(error)
    ))
    }
  }
 </script>

inputにファイルのデータが入ったら、methodsの“selectedOrderFile”が発火。

②クリックしたら“order_file_import()”が発火。

register_order_fileCSVファイルを保存。

FormDataCSVデータを整え、axios.postRailsに送信。

Rails

コントローラー

orders_controller.rb

 class Api::V1::OrdersController < ApiController
 def import
   Order.import(params[:file])
   redirect_to '/'
  end
 end

Vueから受け取ったCSVデータをモデルに渡す。

モデル

Order.rb

 class Order < ApplicationRecord

 def self.import(file)
  CSV.parse(File.read(file).encode("UTF-8",:invalid => :replace),
   headers: true,
   col_sep: "\t",
   header_converters: lambda { |h| h.downcase.gsub(' ', '_')}).each do |row|
   order = find_by(order_id: row["order_id"]) || new
   order.attributes = row.to_hash.slice(*updatable_attributes)
   order.save!(validate: false)
   end
  end
 end

 

CSVファイルをデータベースに登録できる状態に整え、1行ずつeachで取り出す。

order_idが見つかれば、レコードを呼び出し、見つかれなければ、新しく作成。

CSVからデータを取得し、設定する。

④データベースに保存。

 

以上で、CSV、TSVファイルをデータベースに登録することができました!