Notez la nécessité d'importer plusieurs fichiers CSV dans leurs tables respectives à l'aide de Vue.js et de l'API Rails.
Il est écrit par un débutant qui apprend Rails, Vue.js sous forme de mémorandum. Il est possible que le contenu contienne des erreurs et qu'il existe une meilleure méthode, veuillez donc garder cela à l'esprit lorsque vous y faites référence. Si vous avez des questions, n'hésitez pas à commenter.
Je veux préparer une boîte de saisie et utiliser axios pour POSTER dans la table où les fichiers CSV sélectionnés (2 types) sont préparés respectivement.
csv1 ⇨ table codes_lists csv2 ⇨ tableau des finances La définition de la table est la suivante.
code_tableau des listes
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
tableau des finances
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
Ajoutez la bibliothèque à l'avance.
config/application.rb
require 'csv' #Postscript
Ajouter Gem roo et bundle install
Gemfile
gem 'roo'
Puisque des contre-mesures de jeton csrf
sont nécessaires au moment de ʻaxios-post, définissez un plug-in séparé. Créez un nouveau dossier
plugins`.
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
}
}
})
}
Importez le plug-in dans le fichier d'entrée
hello_vue.js
import Vue from "vue/dist/vue.esm";
import axios from "axios"; //ajouter à
import VueAxiosPlugin from "./plugins/vue-axios"; //ajouter à
import App from "./components/App.vue";
Vue.use(VueAxiosPlugin, { axios: axios }) //ajouter à
new Vue({
el: "#app",
render: h => h(App),
})
J'ai défini le routage comme suit: Seules les pièces nécessaires sont répertoriées. Chacun a des paramètres de routage de l'API Rails. Fichier CSV pour la table code_lists vers api / code_lists / import POST le fichier csv pour la table des finances dans api / financials / import.
config/routes.rb
Rails.application.routes.draw do
(Omis ci-dessus)
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
(Omis ci-dessous)
end
View La vue ressemble à ceci:
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">Télécharger la liste de codes</button>
</div>
<div class="import-form">
<button @click="upload('/api/financials/import')" type="submit">Télécharger des données financières</button>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
data: function(){
return {
uploadFile: null
};
},
methods: {
selectedFile: function(e) {
//Enregistrer les informations du fichier sélectionné
e.preventDefault();
let files = e.target.files;
this.uploadFile = files[0];
},
upload: function(url) {
//Fichier POST à l'aide de 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) {
//traitement des réponses
})
.catch(function(error) {
//la gestion des erreurs
})
}
}
}
</script>
Après avoir sélectionné le fichier dans la zone de saisie, enregistrez le fichier dans uploadFile avec la méthode selectedFile. Ensuite, la méthode de téléchargement est exécutée dans l'événement de clic du bouton. POSTER le fichier à l'url de l'argument de la méthode de téléchargement (les deux URL que vous avez définies dans les routes plus tôt). Le fait est que le uploadFile enregistré à l'avance est passé à l'objet FormData lors du POSTing. J'ai commenté parce que je n'ai pas utilisé la configuration cette fois.
Cette fois, ce sera une implémentation qui importe deux fichiers csv dans chaque table, et l'implémentation est requise pour chaque modèle, mais comme le contenu est presque le même, seule l'implémentation du modèle financier est décrite. Tout d'abord sur le contrôleur.
app/controllers/api/financials_controller.rb
class Api::FinancialsController < ApplicationController
def import
Financial.import(params[:file])
end
end
Le contrôleur appelle uniquement la méthode Class de Financial Class.
Ensuite, la description du modèle financier est la suivante.
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|
#Si l'ID est trouvé, appelez l'enregistrement, s'il n'est pas trouvé, créez-en un nouveau
financial = find_by(edinet: row["edinet"], rec_date: row["rec_date"], account_name: row["account_name"]) || new
#Obtenez des données de CSV et définissez
financial.attributes = row.to_hash.slice(*updatable_attributes)
#enregistrer
financial.save
end
end
def self.updatable_attributes
["edinet", "rec_date", "account_name", "value"]
end
end
Entrez le nom de colonne du CSV que vous souhaitez importer dans updatable_attributes. En outre, find_by est utilisé pour vérifier si l'enregistrement a déjà été importé, et s'il a déjà été importé, il sera écrasé.
Si vous avez des questions, n'hésitez pas à commenter. Nous développons une application qui utilise les données financières des sociétés cotées. Nous développons le front-end en utilisant Vue.js et le back-end en utilisant l'API Rails. Je voudrais continuer à résumer les conclusions que j'ai acquises dans un article. Merci d'être resté avec nous jusqu'à présent!
Articles auxquels j'ai fait référence: Contre-mesure csrf: [Vue] axios peut définir le jeton CSRF par défaut Implémentation front-end: Lorsque vous souhaitez publier un fichier avec Vue.js Implémentation du backend: [Ruby on Rails] import CSV
Recommended Posts