Я новичок в Laravel Vue, напишите код для функции CURD, все работает нормально, кроме проверки на стороне сервера. Я получаю 422 с этим сообщением об ошибке: {"message": "Указанные данные недействительны.", "Errors": {"iso": ["Требуется поле iso."]}}
Запрос Полезная нагрузка: {страны: [,…]} страны: [,…] 0: {id: 2, iso: "UK", idd: "44", en_GB: "United Kingom", zh_HK: "UK", zh_CN: "UK", local: "UK", in_use: 1,…} 1: {id: 1, iso: "US", idd: "1", en_GB: "USA", zh_HK: "US", zh_CN: " US ", local:" US ", in_use: 1,…}
Среда: mariaDB 10 PHP 7.3.19, nodejs 12.16.3 composer 1.10.6 laravel 7.6.1 Homestead v10.8.1 virtualbox 6.1 Vue 2.6.11
связанные коды: countryManager. vue, CountrySwitch. vue, store / index. js, Amdin / CountryController. php, Country . php.
counryManger. vue
<template>
<v-container>
<v-layout>
<v-flex>
<v-card class="mx-auto" >
<v-system-bar color="indigo darken-2" dark>
<v-spacer></v-spacer>
<v-icon>mdi-window-minimize</v-icon>
<v-icon>mdi-window-maximize</v-icon>
<v-icon>mdi-close</v-icon>
</v-system-bar>
<v-toolbar color="indigo" dark>
<v-app-bar-nav-icon></v-app-bar-nav-icon>
<v-toolbar-title>Country table maintenance</v-toolbar-title>
<v-spacer></v-spacer>
<v-btn icon>
<v-icon>mdi-magnify</v-icon>
</v-btn>
</v-toolbar>
<v-card-text color="indigo darken-2" dark>
<div class="flex-table">
<div>ISO</div>
<div>English</div>
<div>Chinese Traditional</div>
<div>Chinese Simplified</div>
<div>Local Name</div>
<div>Idd Dialing Code</div>
<div>Remarks</div>
<div>
<v-icon @click="addCountry()">fa fa-plus-circle</v-icon>
<v-icon @click="trashedCountry()">fa fa-recycle</v-icon>
</div>
</div>
<div v-for="(country, index) in countries" :key="country.id" class="flex-table">
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.iso"></v-text-field>
</div>
<div v-else>
{{country.iso}}
</div>
</div>
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.en_GB" ></v-text-field>
</div>
<div v-else>
{{country.en_GB}}
</div>
</div>
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.zh_HK" ></v-text-field>
</div>
<div v-else>
{{country.zh_HK}}
</div>
</div>
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.zh_CN" ></v-text-field>
</div>
<div v-else>
{{country.zh_CN}}
</div>
</div>
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.local" ></v-text-field>
</div>
<div v-else>
{{country.local}}
</div>
</div>
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.idd" ></v-text-field>
</div>
<div v-else>
{{country.idd}}
</div>
</div>
<div>
<div v-if="countryEditingId ==country.id">
<v-text-field v-model="country.remarks"></v-text-field>
</div>
<div v-else>
{{country.remarks}}
</div>
</div>
<div>
<div v-if="!country.deleted_at">
<div v-if="countryEditingId ==country.id">
<v-btn x-small @click="saveCountries(country)">Save</v-btn>
</div>
<div v-else>
<v-btn x-small @click="setToEditing(country)">Edit</v-btn>
</div>
</div>
<div v-if="!country.deleted_at">
<div v-if="countryEditingId ==country.id">
<v-btn x-small @click="resetCountries()">Cancel</v-btn>
</div>
<div v-else>
<v-btn x-small @click="removeCountries(index)">Remove</v-btn>
</div>
</div>
<div v-else>
<v-btn x-small @click="restoreCountries(index)">Restore</v-btn>
</div>
</div>
</div>
</v-card-text>
<v-spacer></v-spacer>
<v-card-subtitle class="grey">
<div class="card-footer text-muted">{{ feedback }}</div>
<div v-if="validationErrors"class="card-footer text-muted">{{ validationErrors }}</div>
</v-card-subtitle>
</v-card>
</v-flex>
</v-layout>
</v-container>
</template>
<script>
export default {
data(){
return {
countryEditingId:''
};
},
computed: {
validationErrors(){
return this.$store.state.validationErrors;
},
countries(){
return this.$store.state.countries;
},
feedback(){
return this.$store.state.feedback;
}
},
methods: {
resetCountries(){
this.countryEditingId = "";
this.$store.dispatch('resetCountries');
},
setToEditing(country){
this.countryEditingId = country.id;
},
addCountry(){
this.$store.commit('ADD_COUNTRIES',{
id:'',
iso:'',
en_GB:'',
zh_HK:'',
zh_CN:'',
idd:'',
remarks:''
});
},
saveCountries(){
this.countryEditingId='';
this.$store.dispatch('saveCountries');
},
updateCountries($event, property, index){
this.countryEditingId='';
this.$store.commit('UPDATE_COUNTRIES',{
index,
property,
value:$event.target.value
});
},
}
}
</script>
<style lang="scss" scoped>
.flex-table {
display: grid;
grid-template-columns: repeat(auto-fill,12%);
padding:5px;
&:nth-of-type(2n) {
background-color: #dedede;
}
.actions {
* {
padding-right: 10px;
}
}
}
</style>
countrySwitch. vue
<template>
<v-app>
<!-- <router-link :to="{name: 'country'}">Country</router-link> -->
<router-view></router-view>
</v-app>
</template>
<script>
import VueRouter from 'vue-router';
import CountryManager from './CountryManager.vue';
import store from '../store';
Vue.use(VueRouter);
export default {
store,
props: ['countries'],
created() {
this.$store.commit('SET_COUNTRIES', _.cloneDeep(this.countries));
},
router: new VueRouter({
mode: 'history',
base: 'country',
routes: [
{
path: '/admin/country',
name: 'country',
component: CountryManager
},
{
path: '/',
redirect: {name: 'country'}
},
]
})
}
</script>
store / index. js
import Vue from 'vue';
import Vuex from 'vuex';
import Axios from 'axios';
Vue.use(Vuex);
export default new Vuex.Store({
state:{
countries:[],
feedback: '',
validationErrors:''
},
mutations :{
SET_COUNTRIES(state, countries){
state.countries = countries;
},
ADD_COUNTRIES(state, countries){
state.countries.push(countries);
},
REMOVE_COUNTRIES(state, index){
state.countries.splice(index, 1);
},
UPDATE_COUNTRIES(state,{index, property, value}){
state.countries[index][property] = value;
},
SET_FEEDBACK(state, feedback){
state.feedback = feedback;
},
SET_ERRORS(state, validationErrors){
state.validationErrors = validationErrors;
},
},
actions:{
saveCountries({commit, state}){
axios.post('/api/countries/upsert',{
countries: state.countries,
})
.then ((res)=>{
if(res.status == 200){
commit('SET_FEEDBACK','Changes Saved');
setTimeout(()=> commit('SET_FEEDBACK',''), 5000);
commit('SET_COUNTRIES', res.data.countries);
}
})
.catch((error)=>{
commit('SET_FEEDBACK','Error: Unable update / insert records');
commit('SET_ERRORS', error.response);
});
},
resetCountries({commit}){
axios.get('/api/countries/list')
.then ((res)=>{
if(res.status == 200){
commit('SET_FEEDBACK','Action Cancelled');
setTimeout(()=> commit('SET_FEEDBACK',''), 5000);
commit('SET_COUNTRIES', res.data.countries);
};
});
},
removeCountries({commit, state}, index){
let id = state.countries[index].id;
if (id > 0){
axios.delete('/api/countries/'+id)
.then((res)=>commit('REMOVE_COUNTRIES',index));
}
commit ('REMOVE_COUNTRIES', index)
},
restoreCountries({commit, state}, index){
let id = state.countries[index].id;
// console.log(id);
if (id > 0){
return axios.put('/api/countries/',{id})
// .then((res)=>console.log(res.status))
.then ((res)=>{
if(res.status == 200){
// console.log(res);
commit('SET_FEEDBACK','Record Restored');
setTimeout(()=> commit('SET_FEEDBACK',''), 5000);
commit('SET_COUNTRIES', res.data.countries);
}
});
}
},
}
});
Amdin / CountryController. php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\country;
use Illuminate\Http\Request;
class CountryController extends Controller
{
/**
* Update and Insert records
*
* @return \Illuminate\Http\Response
*/
public function upsert(Request $request, country $countries)
{
$this->authorize('restore','App\Country');
$this->validate($request, ['iso' => 'required']);
$countries = $request->post('countries');
foreach ($countries as $cou){
if ($cou['id']){
Country::where('id', $cou['id'])->update($cou);
}else{
Country::create($cou);
}
}
$countries = Country::orderBy('en_GB')->get();
return ['countries'=> $countries];
}
}
Страна. php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Country extends Model
{
use SoftDeletes;
protected $guarded = [];
}