[英]Laravel 8: Call to undefined method Illuminate\Database\Eloquent\Relations\HasMany::sync()
[英]Call to undefined method Illuminate\\Database\\Eloquent\\Relations\\BelongsTo::type() [Laravel]
我正在嘗試制作一個 api ,它將在數據庫中創建該單詞后返回單詞的類型(名詞、代詞、動詞等)。 但是由於某種原因,當我的詞匯表 model 中明確定義了類型方法時,我收到“調用未定義方法 Illuminate\Database\Eloquent\Relations\BelongsTo::type()”錯誤。 我沒有使用多對多關系,而是一對多關系(這就是我使用 hasMany() 和 belongsTo 的原因)。 類型有很多詞匯,但詞匯只有一種類型和很多詞匯內容,詞匯內容只有一個與之相關的詞匯。 所以顯然沒有多對多的關系。 很明顯,我的問題不是Call to undefined method (laravel 5.2)的重復。 以下是應用程序的部分代碼。
第一個 model 是 model 類型,它允許我獲取類型的“內容”(此處未列出模型)和屬於特定類型的詞匯表。
型號代碼清單 1:VocType.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VocType extends Model
{
public function contents()
{
return $this->hasMany('App\VocTypeContent');
}
public function vocabularies()
{
return $this->hasMany('App\VocVocabulary');
}
}
這第二個 model 允許我在詞匯表中創建一個單詞,訪問它的“內容”、類型和類別。 這就是問題所在。
型號代碼清單 2:VocVocabulary.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VocVocabulary extends Model
{
protected $fillable = ['voc_category_id','type_id', 'name', 'context', 'picture'];
public $timestamps = false;
public function contents()
{
return $this->hasMany('App\VocVocabularyContent');
}
public function type()
{
return $this->belongsTo('App\VocType');
}
public function category()
{
return $this->belongsTo('App\VocCategory');
}
}
第三個 model 允許我創建詞匯表的內容並訪問它的父詞匯表。
模型代碼清單 3:VocVocabularyContent.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class VocVocabularyContent extends Model
{
protected $fillable = ['voc_vocabulary_id','lang_id', 'content', 'context', 'romanization', 'pronunciation', 'audio'];
public $timestamps = false;
public function vocabulary()
{
return $this->belongsTo('App\VocVocabulary');
}
}
以下是用於上述模型的三個遷移。
遷移代碼清單 1:create_voc_types_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateVocTypesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('voc_types', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('abbreviation');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('voc_types');
}
}
遷移代碼清單 2:create_voc_vocabularies_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateVocVocabulariesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('voc_vocabularies', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('cat_id');
$table->unsignedInteger('type_id');
$table->foreign('cat_id')->references('id')->on('voc_categories')->onDelete('cascade');
$table->foreign('type_id')->references('id')->on('voc_types')->onDelete('cascade');
$table->string('name');
$table->string('context');
$table->string('picture');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('voc_vocabularies');
}
}
遷移代碼清單 3:create_voc_vocabulary_contents_table.php
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateVocVocabularyContentsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('voc_vocabulary_contents', function (Blueprint $table) {
$table->primary(['voc_id', 'lang_id']);
$table->unsignedInteger('voc_id');
$table->unsignedInteger('lang_id');
$table->foreign('voc_id')->references('id')->on('voc_vocabularies')->onDelete('cascade');
$table->foreign('lang_id')->references('id')->on('languages')->onDelete('cascade');
$table->string('content');
$table->string('context');
$table->string('romanization');
$table->string('pronunciation');
$table->string('audio');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('voc_vocabulary_contents');
}
}
這是 controller,我在其中調用詞匯表的 type() 方法。 基本上我有一個 html 表單,如果請求中沒有提供 id,則會創建一個詞匯表(如果語言是英語),它會向這個控制器的方法(postVocabularyAPI)發送一個發布請求。 然后,無論請求是否提供了 id,該方法都會為給定的 id 創建一個詞匯“內容”(如果沒有提供 id,則給定的 id 將是先前創建的詞匯的 id)。 然后 postVocabularyAPI 方法將返回一個 json 響應,其中包含詞匯表類型的 id。
控制器代碼清單 1:Vocabulearn.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Language;
use App\VocTheme;
use App\VocCategory;
use App\VocCategoryContent;
use App\VocVocabulary;
use App\VocVocabularyContent;
use App\VocType;
class Vocabulearn extends Controller
{
//other methods above
public function postVocabularyAPI(Request $request, $language, $theme, $category){
$vocabulary_id = $request->vocabulary_id;
if($vocabulary_id === NULL){
if($language == "english"){
$vocabulary = VocVocabulary::create([
'voc_category_id' => VocCategory::where("slug", $category)->get()->first()->id,
'type_id' => VocType::where("abbreviation", $request->type)->get()->first()->id,
'name' => ucfirst(addslashes($request->translation)),
'context' => $request->context,
'picture' => ''
]);
$vocabulary_id = $vocabulary->id;
} else {
echo '{"success":false, "message":"Create first the English Vocabulary"}';
}
}
$vocabularyContent = VocVocabularyContent::where('lang_id', '=', Language::where("slug", $language)->get()->first()->id)
->where('voc_vocabulary_id', '=', $vocabulary_id)
->first();
if($vocabularyContent !== NULL){
$vocabularies = DB::table('voc_vocabulary_contents')
->where('lang_id', '=', Language::where("slug", $language)->get()->first()->id)
->where('voc_vocabulary_id', '=', $vocabulary_id)
->delete();
}
$vocabularyContent = VocVocabularyContent::create([
'voc_vocabulary_id' => $vocabulary_id,
'lang_id' => Language::where("slug", $language)->get()->first()->id,
'content' => ucfirst(addslashes($translation)),
'context' => addslashes($context),
'romanization' => strtolower(addslashes($romanization)),
'pronunciation' => $pronunciation,
'audio' => $request->audio
]);
echo '{"success":true, "type":"'.stripslashes(html_entity_decode($vocabularyContent->vocabulary()->type()->id)).'"}';
}
}
這樣做給了我一個
“調用未定義的方法 Illuminate\Database\Eloquent\Relations\BelongsTo::type()”
即使我改變
echo '{"success":true, "type":"'.stripslashes(html_entity_decode($vocabularyContent->vocabulary()->type()->id)).'"}';
經過
echo '{"success":true, "type":"'.stripslashes(html_entity_decode($vocabularyContent->vocabulary()->get()->first()->type()->id)).'"}';
我收到一條錯誤消息
“呼叫成員 function type() on null”
這是不對的,因為數據庫已正確填充,所以我不應該得到 null 詞匯表。
有一個快速的解決方案。
首先在VocVocabulary
model type
function 中添加外鍵
public function type()
{
return $this->belongsTo('App\VocType', 'type_id');
}
然后去掉括號
echo $vocabularyContent->type->id;
但這不是做到這一點的標准方法。 您需要以標准方式設置您的關系,以幫助 Laravel 了解您的關系。
首先,您需要將 function 名稱更改為 model 名稱的 camelCase。 例如,由於您的類型 model 名稱是VocType
,因此您的type
function 應更改為
public function type()
至
public function vocType()
{
return $this->belongsTo('App\VocType'); //you don't need a foreign key here
}
在這種情況下,您告訴 laravel function vocType
的目標是VocType
model。 此外,您需要將VocVocabulary
表中的外鍵從type_id
更改為voc_type_id
。 通過這種方式 Laravel 清楚地了解您的關系,否則您需要付出額外的努力來教 laravel 關於您的關系。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.