Laravel8 | Vuex:POST 错误 500(内部服务器错误)
Laravel8 | Vuex: POST error 500 (Internal Server Error)
过去 2 个月我一直在学习 Vue 和 Laravel,最近我开始从事一个项目,以便应用我到目前为止学到的所有知识。我成功地设置了几个 GET 和 POST 路由,但由于某种原因,这个请求一直失败。
我正在尝试使用 Vuex、Laravel 和 Axios 设置一个简单的 POST 请求,但我一直收到 500(内部服务器错误),我不确定是什么原因造成的。我觉得可能是模型设置不正确,如果我输出控制器接收到的数据,它看起来是正确的,但是当我实例化模型并将数据保存到数据库时,我得到了错误。
我非常感谢对我的代码的任何帮助或反馈,因为我处于学习曲线的早期阶段,并且我确信有些事情可以优化。
路线:
//StreamingProviders
Route::get('/api/all-streaming-providers', [StreamingProviderController::class, 'getAllStreamingProviders']);
Route::post('/api/add-streaming-providers', [StreamingProviderController::class, 'addStreamingProviders']);
控制器:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Repository\Dictionaries\StreamingProvidersList;
use App\Models\StreamingProvider;
class StreamingProviderController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function getAllStreamingProviders()
{
$streamingProviders = StreamingProvidersList::$map;
return response()->json([
'allProviders' => $streamingProviders
]);
}
public function addStreamingProviders(Request $request, StreamingProvider $userStreamingProviders)
{
$user = auth()->user();
$data = $request->all();
$userStreamingProviders = new StreamingProvider();
$userStreamingProviders->user_id = $user['id'];
$userStreamingProviders->Netflix = $request->input('Netflix');
$userStreamingProviders->Amazon_Prime_Video = $request->input('Amazon Prime Video');
$userStreamingProviders->Sky_Ticket = $request->input('Sky Ticket');
$userStreamingProviders->Disney_Plus = $request->input('Disney Plus');
$userStreamingProviders->HBO_Video = $request->input('HBO Video');
$userStreamingProviders->save();
return response()->json([
'streamingProviders' => $userStreamingProviders
]);
}
}
FormComponent.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="card">
<div class="card-header">
<h2>Select your streaming country</h2>
</div>
<form @submit.prevent="updateUserDetails()">
<div class="card-body">
<div class="form-control">
<select class="selectpicker" id="countryList">
<option v-for="(value, name) in getCountriesList" :key="name" :value="name">
{{ value }}
</option>
</select>
</div>
<div v-for="(value, name) in getAllStreamingProviders" :key="name" class="form-check">
<input v-model="streamingProviders[value]"
type="checkbox"
:id="name"
:value="value"
:name="streamingProviders[value]"
class="form-check-input" />
<label>{{ value }}</label>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success center-text">Save</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import router from '../../routes/index';
export default {
name: 'edituserdetails',
data() {
return {
value: '',
streamingProviders: {
'Netflix': false,
'Amazon Prime Video': false,
'Disney Plus': false,
'HBO Video': false,
'Sky Ticket': false
}
}
},
created() {
this.$store.dispatch('getCountriesList'),
this.$store.dispatch('getAllStreamingProviders')
},
methods: {
updateUserDetails() {
const country = {
'id': $('#countryList').children("option:selected").val(),
'name': $('#countryList').children("option:selected").text()
};
this.$store.dispatch('updateUserStreamingProviders', this.streamingProviders);
this.$store.dispatch('updateCountry', country).then(() => {
router.push('/user-settings');
});
}
},
computed: {
...mapGetters(['getCountriesList', 'getAllStreamingProviders']),
}
}
</script>
Vuex 商店:
import axios from "axios";
const state = {
userName: "",
country: "",
countriesList: {},
allStreamingProviders: {},
userStreamingProviders: []
};
const mutations = {
UPDATE_USERNAME(state, payload) {
state.userName = payload;
},
GET_COUNTRIES_LIST(state, payload) {
state.countriesList = payload;
},
UPDATE_COUNTRY(state, payload) {
state.country = payload;
},
GET_ALL_STREAMING_PROVIDERS(state, payload) {
state.allStreamingProviders = payload;
},
UPDATE_STREAMING_PROVIDERS(state, payload) {
state.userStreamingProviders = payload;
}
};
const actions = {
updateUserData({ commit }) {
axios.get("/api/user").then(response => {
commit("UPDATE_USERNAME", response.data.name);
commit("UPDATE_COUNTRY", response.data.country);
});
},
getCountriesList({ commit }) {
axios.get("/api/countries-list").then(response => {
commit("GET_COUNTRIES_LIST", response.data.list);
});
},
updateCountry({ commit }, country) {
axios
.post("/api/update-country", country)
.then(response => {
commit("UPDATE_COUNTRY", response.data.country);
})
.catch(err => {
console.log(err);
});
},
getAllStreamingProviders({ commit }) {
axios.get("/api/all-streaming-providers").then(response => {
commit("GET_ALL_STREAMING_PROVIDERS", response.data.allProviders);
});
},
updateUserStreamingProviders({ commit }, streamingProviders) {
axios
.post("/api/add-streaming-providers", streamingProviders)
.then(response => {
commit(
"UPDATE_STREAMING_PROVIDERS",
response.data.streamingProviders
);
})
.catch(err => {
console.log(err);
});
}
};
const getters = {
getUserName: state => state.userName,
getCountry: state => state.country,
getCountriesList: state => state.countriesList,
getAllStreamingProviders: state => state.allStreamingProviders
};
const userStore = {
state,
mutations,
actions,
getters
};
export default userStore;
流媒体提供商模型:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class StreamingProvider extends Model
{
use HasFactory;
/**
* Attributes that are mass assignable
*
* @var array
*/
protected $fillable = ['user_id', 'Netflix', 'Amazon_Prime_Video', 'Sky_Ticket', 'Disney_Plus', 'HBO_Video'];
protected $table = 'streaming_provider';
protected $cast = [
'Netflix' => 'boolean',
'Amazon_Prime_Video' => 'boolean',
'Sky_Ticket' => 'boolean',
'Disney_Plus' => 'boolean',
'HBO_Video' => 'boolean'
];
public function user()
{
return $this->belongsTo(User::class);
}
}
在将数据保存到数据库之前是否必须转换数据?
布尔属性是否被视为 $fillable ??
迁移:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class StreamingProvidersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('streaming_provider', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->boolean('Netflix')->default(0);
$table->boolean('Amazon_Prime_Video')->default(0);
$table->boolean('Sky_Ticket')->default(0);
$table->boolean('Disney_Plus')->default(0);
$table->boolean('HBO_Video')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('streaming_provider');
}
}
Laravel.log:
[2021-10-27 09:12:39] local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `streaming_provider` (`user_id`, `Netflix`, `Amazon_Prime_Video`, `Sky_Ticket`, `Disney_Plus`, `HBO_Video`, `updated_at`, `created_at`) values (1, 1, 1, 0, 0, 0, 2021-10-27 09:12:39, 2021-10-27 09:12:39)) {"userId":1,"exception":"[object] (Illuminate\Database\QueryException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `streaming_provider` (`user_id`, `Netflix`, `Amazon_Prime_Video`, `Sky_Ticket`, `Disney_Plus`, `HBO_Video`, `updated_at`, `created_at`) values (1, 1, 1, 0, 0, 0, 2021-10-27 09:12:39, 2021-10-27 09:12:39)) at C:\xampp\htdocs\laravel_vue\Fullstack_Project_Movie_III\vendor\laravel\framework\src\Illuminate\Database\Connection.php:703)
[previous exception] [object] (PDOException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' at C:\xampp\htdocs\laravel_vue\Fullstack_Project_Movie_III\vendor\laravel\framework\src\Illuminate\Database\Connection.php:486)
谢谢大家!!
出现此错误是因为迁移中缺少 $table->timestamps();
,因此您必须添加它,Laravel 会自动为您创建 updated_at
和 created_at
列。
对于 laravel 中的每个条目和更新,它会自动为这些列分配值,因此很明显,当它们从数据库中丢失时,您会收到此错误。
之后,您的迁移将如下所示:
`Schema::create('streaming_provider', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->boolean('Netflix')->default(0);
$table->boolean('Amazon_Prime_Video')->default(0);
$table->boolean('Sky_Ticket')->default(0);
$table->boolean('Disney_Plus')->default(0);
$table->boolean('HBO_Video')->default(0);
$table->timestamps();
});`
过去 2 个月我一直在学习 Vue 和 Laravel,最近我开始从事一个项目,以便应用我到目前为止学到的所有知识。我成功地设置了几个 GET 和 POST 路由,但由于某种原因,这个请求一直失败。 我正在尝试使用 Vuex、Laravel 和 Axios 设置一个简单的 POST 请求,但我一直收到 500(内部服务器错误),我不确定是什么原因造成的。我觉得可能是模型设置不正确,如果我输出控制器接收到的数据,它看起来是正确的,但是当我实例化模型并将数据保存到数据库时,我得到了错误。
我非常感谢对我的代码的任何帮助或反馈,因为我处于学习曲线的早期阶段,并且我确信有些事情可以优化。
路线:
//StreamingProviders
Route::get('/api/all-streaming-providers', [StreamingProviderController::class, 'getAllStreamingProviders']);
Route::post('/api/add-streaming-providers', [StreamingProviderController::class, 'addStreamingProviders']);
控制器:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Repository\Dictionaries\StreamingProvidersList;
use App\Models\StreamingProvider;
class StreamingProviderController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function getAllStreamingProviders()
{
$streamingProviders = StreamingProvidersList::$map;
return response()->json([
'allProviders' => $streamingProviders
]);
}
public function addStreamingProviders(Request $request, StreamingProvider $userStreamingProviders)
{
$user = auth()->user();
$data = $request->all();
$userStreamingProviders = new StreamingProvider();
$userStreamingProviders->user_id = $user['id'];
$userStreamingProviders->Netflix = $request->input('Netflix');
$userStreamingProviders->Amazon_Prime_Video = $request->input('Amazon Prime Video');
$userStreamingProviders->Sky_Ticket = $request->input('Sky Ticket');
$userStreamingProviders->Disney_Plus = $request->input('Disney Plus');
$userStreamingProviders->HBO_Video = $request->input('HBO Video');
$userStreamingProviders->save();
return response()->json([
'streamingProviders' => $userStreamingProviders
]);
}
}
FormComponent.vue
<template>
<div class="container">
<div class="row justify-content-center">
<div class="card">
<div class="card-header">
<h2>Select your streaming country</h2>
</div>
<form @submit.prevent="updateUserDetails()">
<div class="card-body">
<div class="form-control">
<select class="selectpicker" id="countryList">
<option v-for="(value, name) in getCountriesList" :key="name" :value="name">
{{ value }}
</option>
</select>
</div>
<div v-for="(value, name) in getAllStreamingProviders" :key="name" class="form-check">
<input v-model="streamingProviders[value]"
type="checkbox"
:id="name"
:value="value"
:name="streamingProviders[value]"
class="form-check-input" />
<label>{{ value }}</label>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-success center-text">Save</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import router from '../../routes/index';
export default {
name: 'edituserdetails',
data() {
return {
value: '',
streamingProviders: {
'Netflix': false,
'Amazon Prime Video': false,
'Disney Plus': false,
'HBO Video': false,
'Sky Ticket': false
}
}
},
created() {
this.$store.dispatch('getCountriesList'),
this.$store.dispatch('getAllStreamingProviders')
},
methods: {
updateUserDetails() {
const country = {
'id': $('#countryList').children("option:selected").val(),
'name': $('#countryList').children("option:selected").text()
};
this.$store.dispatch('updateUserStreamingProviders', this.streamingProviders);
this.$store.dispatch('updateCountry', country).then(() => {
router.push('/user-settings');
});
}
},
computed: {
...mapGetters(['getCountriesList', 'getAllStreamingProviders']),
}
}
</script>
Vuex 商店:
import axios from "axios";
const state = {
userName: "",
country: "",
countriesList: {},
allStreamingProviders: {},
userStreamingProviders: []
};
const mutations = {
UPDATE_USERNAME(state, payload) {
state.userName = payload;
},
GET_COUNTRIES_LIST(state, payload) {
state.countriesList = payload;
},
UPDATE_COUNTRY(state, payload) {
state.country = payload;
},
GET_ALL_STREAMING_PROVIDERS(state, payload) {
state.allStreamingProviders = payload;
},
UPDATE_STREAMING_PROVIDERS(state, payload) {
state.userStreamingProviders = payload;
}
};
const actions = {
updateUserData({ commit }) {
axios.get("/api/user").then(response => {
commit("UPDATE_USERNAME", response.data.name);
commit("UPDATE_COUNTRY", response.data.country);
});
},
getCountriesList({ commit }) {
axios.get("/api/countries-list").then(response => {
commit("GET_COUNTRIES_LIST", response.data.list);
});
},
updateCountry({ commit }, country) {
axios
.post("/api/update-country", country)
.then(response => {
commit("UPDATE_COUNTRY", response.data.country);
})
.catch(err => {
console.log(err);
});
},
getAllStreamingProviders({ commit }) {
axios.get("/api/all-streaming-providers").then(response => {
commit("GET_ALL_STREAMING_PROVIDERS", response.data.allProviders);
});
},
updateUserStreamingProviders({ commit }, streamingProviders) {
axios
.post("/api/add-streaming-providers", streamingProviders)
.then(response => {
commit(
"UPDATE_STREAMING_PROVIDERS",
response.data.streamingProviders
);
})
.catch(err => {
console.log(err);
});
}
};
const getters = {
getUserName: state => state.userName,
getCountry: state => state.country,
getCountriesList: state => state.countriesList,
getAllStreamingProviders: state => state.allStreamingProviders
};
const userStore = {
state,
mutations,
actions,
getters
};
export default userStore;
流媒体提供商模型:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class StreamingProvider extends Model
{
use HasFactory;
/**
* Attributes that are mass assignable
*
* @var array
*/
protected $fillable = ['user_id', 'Netflix', 'Amazon_Prime_Video', 'Sky_Ticket', 'Disney_Plus', 'HBO_Video'];
protected $table = 'streaming_provider';
protected $cast = [
'Netflix' => 'boolean',
'Amazon_Prime_Video' => 'boolean',
'Sky_Ticket' => 'boolean',
'Disney_Plus' => 'boolean',
'HBO_Video' => 'boolean'
];
public function user()
{
return $this->belongsTo(User::class);
}
}
在将数据保存到数据库之前是否必须转换数据? 布尔属性是否被视为 $fillable ??
迁移:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class StreamingProvidersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('streaming_provider', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->boolean('Netflix')->default(0);
$table->boolean('Amazon_Prime_Video')->default(0);
$table->boolean('Sky_Ticket')->default(0);
$table->boolean('Disney_Plus')->default(0);
$table->boolean('HBO_Video')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('streaming_provider');
}
}
Laravel.log:
[2021-10-27 09:12:39] local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `streaming_provider` (`user_id`, `Netflix`, `Amazon_Prime_Video`, `Sky_Ticket`, `Disney_Plus`, `HBO_Video`, `updated_at`, `created_at`) values (1, 1, 1, 0, 0, 0, 2021-10-27 09:12:39, 2021-10-27 09:12:39)) {"userId":1,"exception":"[object] (Illuminate\Database\QueryException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' (SQL: insert into `streaming_provider` (`user_id`, `Netflix`, `Amazon_Prime_Video`, `Sky_Ticket`, `Disney_Plus`, `HBO_Video`, `updated_at`, `created_at`) values (1, 1, 1, 0, 0, 0, 2021-10-27 09:12:39, 2021-10-27 09:12:39)) at C:\xampp\htdocs\laravel_vue\Fullstack_Project_Movie_III\vendor\laravel\framework\src\Illuminate\Database\Connection.php:703)
[previous exception] [object] (PDOException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'updated_at' in 'field list' at C:\xampp\htdocs\laravel_vue\Fullstack_Project_Movie_III\vendor\laravel\framework\src\Illuminate\Database\Connection.php:486)
谢谢大家!!
出现此错误是因为迁移中缺少 $table->timestamps();
,因此您必须添加它,Laravel 会自动为您创建 updated_at
和 created_at
列。
对于 laravel 中的每个条目和更新,它会自动为这些列分配值,因此很明显,当它们从数据库中丢失时,您会收到此错误。
之后,您的迁移将如下所示:
`Schema::create('streaming_provider', function (Blueprint $table) {
$table->id();
$table->string('user_id');
$table->boolean('Netflix')->default(0);
$table->boolean('Amazon_Prime_Video')->default(0);
$table->boolean('Sky_Ticket')->default(0);
$table->boolean('Disney_Plus')->default(0);
$table->boolean('HBO_Video')->default(0);
$table->timestamps();
});`