Notieren Sie sich die Notwendigkeit, mehrere CSV-Dateien mithilfe von Vue.js und der Rails-API in ihre jeweiligen Tabellen zu importieren.
Es wurde von einem Anfänger geschrieben, der Rails, Vue.js, als Memorandum lernt. Es besteht die Möglichkeit, dass der Inhalt Fehler enthält, und es besteht die Möglichkeit, dass es eine bessere Methode gibt. Denken Sie also bitte daran, wenn Sie darauf verweisen. Wenn Sie Fragen haben, können Sie diese gerne kommentieren.
Ich möchte ein Eingabefeld vorbereiten und Axios verwenden, um in die Tabelle zu POSTEN, in der die ausgewählten CSV-Dateien (2 Typen) jeweils vorbereitet sind.
Tabelle csv1 ⇨ code_lists csv2 ⇨ Finanztabelle Die Tabellendefinition lautet wie folgt.
code_listet Tabelle auf
create_table "code_lists", force: :cascade do |t|
t.string "edinet"
t.string "securities"
t.string "company"
t.string "sector"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["company"], name: "index_code_lists_on_company"
t.index ["edinet"], name: "index_code_lists_on_edinet", unique: true
t.index ["securities"], name: "index_code_lists_on_securities"
end
Finanztabelle
create_table "financials", force: :cascade do |t|
t.string "edinet"
t.date "rec_date"
t.string "account_name"
t.float "value"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.index ["account_name"], name: "index_financials_on_account_name"
t.index ["edinet", "rec_date", "account_name"], name: "index_financials_on_edinet_and_rec_date_and_account_name", unique: true
t.index ["edinet"], name: "index_financials_on_edinet"
end
Fügen Sie die Bibliothek im Voraus hinzu.
config/application.rb
require 'csv' #Nachtrag
Fügen Sie Gem Roo und "Bundle Install" hinzu
Gemfile
gem 'roo'
Da zum Zeitpunkt von "axios-post" "csrf" -Token-Gegenmaßnahmen erforderlich sind, setzen Sie ein separates Plug-In. Erstellen Sie einen neuen Plugins-Ordner.
app/javascript/packs/plugins/vue-axios.js
const VueAxiosPlugin = {}
export default VueAxiosPlugin.install = function(Vue, { axios }) {
const csrf_token = document.querySelector('meta[name="csrf-token"]').getAttribute('content')
axios.defaults.headers.common = {
"X-Requested-With": "XMLHttpRequest",
"X-CSRF-Token": csrf_token
}
Vue.axios = axios
Object.defineProperties(Vue.prototype, {
axios: {
get () {
return axios
}
}
})
}
Importieren Sie das Plug-In in die Eingabedatei
hello_vue.js
import Vue from "vue/dist/vue.esm";
import axios from "axios"; //hinzufügen
import VueAxiosPlugin from "./plugins/vue-axios"; //hinzufügen
import App from "./components/App.vue";
Vue.use(VueAxiosPlugin, { axios: axios }) //hinzufügen
new Vue({
el: "#app",
render: h => h(App),
})
Ich stelle das Routing wie folgt ein: Es werden nur die erforderlichen Teile aufgelistet. Jedes hat Rails API-Routing-Einstellungen. CSV-Datei für die Tabelle code_lists in api / code_lists / import POSTEN Sie die CSV-Datei für die Finanztabelle an api / Financials / Import.
config/routes.rb
Rails.application.routes.draw do
(Oben weggelassen)
namespace :api, format: 'json' do
resources :code_lists do
post :import, on: :collection
end
end
namespace :api, format: 'json' do
resources :financials do
post :import, on: :collection
end
end
(Unten weggelassen)
end
View Die Ansicht sieht folgendermaßen aus:
Import.vue
<template>
<div>
<div class="import-form">
<input @change="selectedFile" type="file" name="file">
</div>
<div class="import-form">
<button @click="upload('/api/code_lists/import')" type="submit">Codeliste hochladen</button>
</div>
<div class="import-form">
<button @click="upload('/api/financials/import')" type="submit">Finanzdaten hochladen</button>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data: function(){
return {
uploadFile: null
};
},
methods: {
selectedFile: function(e) {
//Speichern Sie die Informationen der ausgewählten Datei
e.preventDefault();
let files = e.target.files;
this.uploadFile = files[0];
},
upload: function(url) {
//POST-Datei mit FormData
let formData = new FormData();
formData.append('file', this.uploadFile);
// let config = {
// headers: {
// 'content-type': 'multipart/form-data'
// }
// };
axios
.post(url, formData)
.then(function(response) {
//Antwortverarbeitung
})
.catch(function(error) {
//Fehlerbehandlung
})
}
}
}
</script>
Speichern Sie die Datei nach Auswahl der Datei im Eingabefeld mit der Methode selectedFile in uploadFile. Anschließend wird die Upload-Methode im Klickereignis der Schaltfläche ausgeführt. POSTEN Sie die Datei an die URL des Upload-Methodenarguments (die beiden URLs, die Sie zuvor in Routen festgelegt haben). Der Punkt ist, dass die im Voraus gespeicherte uploadFile beim POSTing an das FormData-Objekt übergeben wird. Ich habe auskommentiert, weil ich diesmal config nicht verwendet habe.
Dieses Mal wird es eine Implementierung sein, die zwei CSV-Dateien in jede Tabelle importiert, und es ist notwendig, sie für jedes Modell zu implementieren. Da der Inhalt jedoch nahezu identisch ist, wird nur die Implementierung des Finanzmodells beschrieben. Zuerst über die Steuerung.
app/controllers/api/financials_controller.rb
class Api::FinancialsController < ApplicationController
def import
Financial.import(params[:file])
end
end
Der Controller ruft nur die Class-Methode der Financial Class auf.
Als nächstes lautet die Beschreibung des Finanzmodells wie folgt.
app/models/financial.rb
class Financial < ApplicationRecord
validates :edinet, presence: true
validates :rec_date, presence: true
validates :account_name, presence: true
validates :value, presence: true
def self.import(file)
CSV.foreach(file.path, headers: true) do |row|
#Wenn die ID gefunden wird, rufen Sie den Datensatz auf. Wenn er nicht gefunden wird, erstellen Sie einen neuen
financial = find_by(edinet: row["edinet"], rec_date: row["rec_date"], account_name: row["account_name"]) || new
#Holen Sie sich Daten von CSV und setzen Sie
financial.attributes = row.to_hash.slice(*updatable_attributes)
#sparen
financial.save
end
end
def self.updatable_attributes
["edinet", "rec_date", "account_name", "value"]
end
end
Geben Sie den Spaltennamen der CSV, die Sie importieren möchten, in updatable_attributes ein. Außerdem wird find_by verwendet, um zu überprüfen, ob der Datensatz bereits importiert wurde. Wenn er bereits importiert wurde, wird er überschrieben.
Wenn Sie Fragen haben, können Sie diese gerne kommentieren. Wir entwickeln eine Anwendung, die die Finanzdaten börsennotierter Unternehmen verwendet. Wir entwickeln das Frontend mit Vue.js und das Backend mit der Rails-API. Ich möchte die Ergebnisse, die ich in einem Artikel gewonnen habe, weiter zusammenfassen. Vielen Dank, dass Sie bisher bei uns geblieben sind!
Artikel, auf die ich mich bezog: csrf-Maßnahmen: [Vue] -Axios können standardmäßig CSRF-Token festlegen Front-End-Implementierung: Wenn Sie eine Datei mit Vue.js veröffentlichen möchten Backend-Implementierung: [Ruby on Rails] CSV-Import
Recommended Posts